Чи може впорядкований список створити результат, схожий на 1,1, 1,2, 1,3 (замість всього 1, 2, 3,…) з використанням css?


201

Чи може впорядкований список створювати результати, схожі на 1.1, 1.2, 1.3 (замість лише 1, 2, 3, ...) за допомогою CSS? Поки що використання використовує list-style-type:decimalлише 1, 2, 3, а не 1,1, 1,2., 1,3.


Я б запропонував порівняти прийняту відповідь з цим Якубом Жируткою. Я думаю, що останнє навіть набагато краще.
Френк Конійн

Елегантне рішення. Будь-яка ідея, чому Вікіпедія використовує ul для своїх змістових розділів замість цього?
Mattypants

1
@davnicwil Я згоден; виглядає так, що я, ймовірно, просто застосував дублікат у неправильному порядку ще у вересні.
TylerH

Круто, зараз я відчуваю ніяковість, бо мені ніколи не приходило в голову, що це може бути проста помилка - вибачення!
davnicwil

Відповіді:


289

Для цього можна використовувати лічильники :

Наведені нижче таблиці стилів вкладені елементи списку як "1", "1.1", "1.1.1" тощо.

OL { counter-reset: item }
LI { display: block }
LI:before { content: counters(item, ".") " "; counter-increment: item }

Приклад

ol { counter-reset: item }
li{ display: block }
li:before { content: counters(item, ".") " "; counter-increment: item }
<ol>
  <li>li element
    <ol>
      <li>sub li element</li>
      <li>sub li element</li>
      <li>sub li element</li>
    </ol>
  </li>
  <li>li element</li>
  <li>li element
    <ol>
      <li>sub li element</li>
      <li>sub li element</li>
      <li>sub li element</li>
    </ol>
  </li>
</ol>

Див. Вкладені лічильники та область для отримання додаткової інформації.


2
чудова відповідь. Яка підтримка в цьому?
Джейсон МакКрірі

1
@Jason McCreary: Ну, це нижня сторона: лічильники не підтримуються в IE до версії 8 .
Gumbo

3
У цьому рішенні пропущена одна крихітна річ: крапка, що слідує за номером елемента. Це не схоже на стандартний стиль списку. Виправте, додавши крапку до правила для li:before: content: counters(item, ".")". ";
LS

4
Це погана відповідь. Не працює належним чином. Ознайомтеся з відповіддю Якуба Жирутки нижче
Пабло Пабло

1
@Gumbo я знаю, і відповідь Якуба дав мені правильну нумерацію.
Пан Пабло

236

Жодне з рішень на цій сторінці не працює коректно та універсально для всіх рівнів та довгих (обгорнутих) абзаців. Дійсно складно досягти послідовного відступу завдяки мінливому розміру маркера (1., 1.2, 1.10, 1.10.5,…); це не може бути просто "підробленим", навіть не заздалегідь обчисленим запасом / прокладкою для кожного можливого рівня відступу.

Я нарешті з’ясував рішення, яке насправді працює і не потребує JavaScript.

Це тестується на Firefox 32, Chromium 37, IE 9 та браузері Android. Не працює на IE 7 та попередніх версіях.

CSS:

ol {
  list-style-type: none;
  counter-reset: item;
  margin: 0;
  padding: 0;
}

ol > li {
  display: table;
  counter-increment: item;
  margin-bottom: 0.6em;
}

ol > li:before {
  content: counters(item, ".") ". ";
  display: table-cell;
  padding-right: 0.6em;    
}

li ol > li {
  margin: 0;
}

li ol > li:before {
  content: counters(item, ".") " ";
}

Приклад: Приклад

Спробуйте його на JSFiddle , розкладіть його на Gist .


1
Гарна робота з досягненням цього типу відступу. Я все ж заперечую, що перші два випадки відступу, які ви перерахували, - це скоріше питання, а не правильно та неправильно. Розглянемо випадок 1 і випадок 2 - останній вдається вичавити набагато більше рівнів, перш ніж інтервал стане непростим, при цьому все ще виглядає досить акуратно. Крім того, MS Word та стиль браузера за замовчуванням застосовують відступи 2. Гадаю, вони теж роблять неправильно?
Сол Фотлі

2
@ saul-fautley Це неправильно з точки зору типографії. Ваш приклад з божевільною кількістю вкладених рівнів демонструє, що вкладена нумерація не підходить для занадто багатьох рівнів, але це досить очевидно. MS Words не є системою набору текстів, це просто документообіг із поганою типографією. Стайлінг браузера за замовчуванням… о, ви мало знаєте про типографіку, чи не так?
Якуб Жирутка

3
Це дійсно працює (технічно) для всіх рівнів і довгих абзаців. Якщо розумно використовувати десятки рівнів, це ще одне питання, яке не має нічого спільного з технічним рішенням. Справа в тому, що вам не потрібно заздалегідь визначати CSS-правило для кожного рівня гніздування, як для деяких інших рішень.
Якуб Жирутка

4
Хоча я б не сказав, що в інших відповідях є щось «не так», я б сказав, що вони неповні. Ця відповідь виявлена ​​на місці, і навіть працював на жахливо химерному стилі сайту, який я вношу на поправку.
DanielM

2
@tremby: розбіжність можна вирішити, використовуючи li використовувати "display: table-row" замість "display: table". Проблема, яку це спричиняє, полягає в тому, що li потім не може використовувати будь-які поля / прокладки, оскільки рядки таблиць завжди розміщуються автоматично за вмістом. Це можна вирішити, додавши "li: after" з "display: block". Повний приклад див. У jsFiddle . Як додатковий бонус я додав "вирівнювання тексту: право" до "лі: до", щоб цифри вирівнялися правильно.
mmlr

64

Обрана відповідь - це чудовий початок, але по суті це змушує list-style-position: inside;стилізувати елементи списку, роблячи загорнутий текст важким для читання. Ось простий спосіб вирішення, який також забезпечує контроль над полем між цифрою та текстом, а також вирівнює число відповідно до поведінки за замовчуванням.

ol {
    counter-reset: item;
}
ol li {
    display: block;
    position: relative;
}
ol li:before {
    content: counters(item, ".")".";
    counter-increment: item;
    position: absolute;
    margin-right: 100%;
    right: 10px; /* space between number and text */
}

JSFiddle: http://jsfiddle.net/3J4Bu/


Одним із мінусів є те, що він додає період до кінця кожного елемента списку.
Студент Давіна

3
@Davin Studer: Це додає лише період до кінця кожного числа, відповідно до olповедінки за замовчуванням . Його можна легко видалити, видаливши останнє "."з contentвластивості, але це мені просто дивно.
Сол Фотлі

14

Розміщені тут рішення не спрацювали добре для мене, тому я зробив суміш із цих питань і наступного питання: Чи можна створити багаторівневий упорядкований список у HTML?

/* Numbered lists like 1, 1.1, 2.2.1... */
ol li {display:block;} /* hide original list counter */
ol > li:first-child {counter-reset: item;} /* reset counter */
ol > li {counter-increment: item; position: relative;} /* increment counter */
ol > li:before {content:counters(item, ".") ". "; position: absolute; margin-right: 100%; right: 10px;} /* print counter */

Результат:

скріншот

Примітка: скріншот, якщо ви хочете побачити вихідний код або що-небудь ще з цієї публікації: http://estiloasertivo.blogspot.com.es/2014/08/introduccion-running-lean-y-lean.html


1
Це найкраща (і найпростіша) робоча відповідь з усієї сторінки.
Бруно Тоффоло

6

Примітка. Використовуйте CSS для створення вкладеної нумерації в сучасному браузері. Дивіться прийняту відповідь. Далі наведено лише для історичного інтересу.counters


Якщо браузер підтримує contentта counter,

.foo {
  counter-reset: foo;
}
.foo li {
  list-style-type: none;
}
.foo li::before {
  counter-increment: foo;
  content: "1." counter(foo) " ";
}
<ol class="foo">
  <li>uno</li>
  <li>dos</li>
  <li>tres</li>
  <li>cuatro</li>
</ol>


Це рішення жахливо виходить з ладу, коли списки вкладені.
LS

@LS Ви завжди можете розмістити селектори відповідно до ваших потреб. .foo > ol > li.
kennytm

1
Моя думка полягає в тому, що ви жорстко "1". в стиль. Що трапляється, коли підліст є дочірньою частиною другого елемента у батьківському списку? Ви хочете, щоб він відображався як "2.", але це завжди буде "1." через те, як тут закодовано. Яке рішення? Створюйте нові набори стилів для кожного можливого числа? Ні. Використовуйте counters()функцію, як у наведених вище прикладах, замість counter()функції.
LS

2
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <meta name="author" content="Sandro Alvares - KingRider">
    </head>
    <body>
        <style type="text/css">
            li.title { 
                font-size: 20px; 
                font-weight: lighter; 
                padding: 15px; 
                counter-increment: ordem; 
            }
            .foo { 
                counter-reset: foo; 
                padding-left: 15px; 
            }
            .foo li { 
                list-style-type: none; 
            }
            .foo li:before { 
                counter-increment: foo; 
                content: counter(ordem) "." counter(foo) " "; 
            }
        </style>
        <ol>
            <li class="title">TITLE ONE</li>
            <ol class="foo">
                <li>text 1 one</li>
                <li>text 1 two</li>
                <li>text 1 three</li>
                <li>text 1 four</li>
            </ol>
            <li class="title">TITLE TWO</li>
            <ol class="foo">
                <li>text 2 one</li>
                <li>text 2 two</li>
                <li>text 2 three</li>
                <li>text 2 four</li>
            </ol>
            <li class="title">TITLE THREE</li>
            <ol class="foo">
                <li>text 3 one</li>
                <li>text 3 two</li>
                <li>text 3 three</li>
                <li>text 3 four</li>
            </ol>
        </ol>
    </body>
</html>

Результат: http://i.stack.imgur.com/78bN8.jpg


2

У мене є певна проблема, коли є два списки, а другий - всередині DIV. Другий список повинен починатися з 1. не 2.1

<ol>
    <li>lorem</li>
    <li>lorem ipsum</li>
</ol>

<div>
    <ol>
        <li>lorem (should be 1.)</li>
        <li>lorem ipsum ( should be 2.)</li>
    </ol>
</div>

http://jsfiddle.net/3J4Bu/364/

EDIT: Я вирішив проблему цим http://jsfiddle.net/hy5f6161/


1

Найближчим часом ви, можливо, зможете використовувати ::markerелемент psuedo для досягнення такого ж результату, як і інші рішення лише в одному рядку коду.

Не забудьте перевірити таблицю сумісності браузера, оскільки це все ще експериментальна технологія. На момент написання лише Firefox та Firefox для Android, починаючи з версії 68, це підтримують.

Ось фрагмент, який відобразиться правильно, якщо його спробувати у сумісному браузері:

::marker { content: counters(list-item,'.') ':' }
li { padding-left: 0.5em }
<ol>
  <li>li element
    <ol>
      <li>sub li element</li>
      <li>sub li element</li>
      <li>sub li element</li>
    </ol>
  </li>
  <li>li element</li>
  <li>li element
    <ol>
      <li>sub li element</li>
      <li>sub li element</li>
      <li>sub li element</li>
    </ol>
  </li>
</ol>

Ви також можете перевірити цю чудову статтю в smashingmagazine на цю тему.


0

Мені потрібно було додати це до рішення, розміщеного в 12 році, оскільки я використовував список із сумішшю упорядкованого списку та не упорядкованих компонентів списків. зміст: не-близька цитата здається дивним, що я додам, я знаю, але це працює ...

ol ul li:before {
    content: no-close-quote;
    counter-increment: none;
    display: list-item;
    margin-right: 100%;
    position: absolute;
    right: 10px;
}

0

Для мене працювало наступне:

ol {
  list-style-type: none;
  counter-reset: item;
  margin: 0;
  padding: 0;
}

ol > li {
  display: table;
  counter-increment: item;
  margin-bottom: 0.6em;
}

ol > li:before {
  content: counters(item, ".") ") ";
  display: table-cell;
  padding-right: 0.6em;
}

li ol > li {
  margin: 0;
}

li ol > li:before {
  content: counters(item, ".") ") ";
}

Подивіться: http://jsfiddle.net/rLebz84u/2/

або цей http://jsfiddle.net/rLebz84u/3/ з більшим та виправданим текстом


Втрата часу на перегляд. Майже ідентичний попередній відповіді. До кінця маркера додано лише різницю ")".
juanitogan

0

це правильний код, якщо ви хочете, щоб перша дитина li змінила розмір інших css.

<style>
    li.title { 
        font-size: 20px; 

        counter-increment: ordem; 
        color:#0080B0;
    }
    .my_ol_class { 
        counter-reset: my_ol_class; 
        padding-left: 30px !important; 
    }
    .my_ol_class li { 
          display: block;
        position: relative;

    }
    .my_ol_class li:before { 
        counter-increment: my_ol_class; 
        content: counter(ordem) "." counter(my_ol_class) " "; 
        position: absolute;
        margin-right: 100%;
        right: 10px; /* space between number and text */
    }
    li.title ol li{
         font-size: 15px;
         color:#5E5E5E;
    }
</style>

у файлі html.

        <ol>
            <li class="title"> <p class="page-header list_title">Acceptance of Terms. </p>
                <ol class="my_ol_class">
                    <li> 
                        <p>
                            my text 1.
                        </p>
                    </li>
                    <li>
                        <p>
                            my text 2.
                        </p>
                    </li>
                </ol>
            </li>
        </ol>
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.