Может ли упорядоченный список привести к результату, который выглядит как 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.

Richard77
источник
Я бы предложил сравнить принятый ответ с ответом Якуба Йирутки. Я думаю, что последний даже намного лучше.
Фрэнк Конейн,
Элегантное решение. Есть идеи, почему Википедия использует ul для своих разделов контента вместо этого?
Штаны
1
@davnicwil Я согласен; Похоже, я только что применил дубликат в неправильном порядке еще в сентябре.
TylerH
Круто, теперь я чувствую себя неловко, поскольку мне никогда не приходило в голову, что это может быть простая ошибка, как это - извинения!
davnicwil

Ответы:

290

Вы можете использовать счетчики для этого:

Следующие номера таблиц стилей нумеруют вложенные элементы списка как «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
@ Джейсон МакКрири: Ну, это обратная сторона: счетчики не поддерживаются в IE до версии 8 .
Гамбо
3
Это решение пропускает одну крошечную вещь: точку, следующую за номером изделия. Это не похоже на стандартный стиль списка. Исправить, добавив точку к правилу для li:before: content: counters(item, ".")". ";
LS
4
Это плохой ответ. Это не работает должным образом. Ознакомьтесь с ответом Якуба Йирутки ниже
г-н Пабло
1
@ Гамбо, я знаю, и ответ Якуба дал мне правильную нумерацию.
г-н Пабло
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 для полного примера. В качестве дополнительного бонуса я добавил «text-align: right» в «li: before», чтобы выровнять числа по правому краю.
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

chelder
источник
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>

kennytm
источник
Это решение ужасно терпит неудачу, когда списки вложены.
LS
@LS Вы всегда можете разместить селекторы в соответствии с вашими потребностями. .foo > ol > li,
Кеннитм
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

KingRider
источник
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/

РЕДАКТИРОВАТЬ: я решил проблему с помощью этого http://jsfiddle.net/hy5f6161/

robertad
источник
1

В ближайшем будущем вы сможете использовать ::markerpsuedo-элемент для достижения того же результата, что и другие решения, всего в одной строке кода.

Не забудьте проверить таблицу совместимости браузера поскольку это все еще экспериментальная технология. На данный момент это поддерживается только 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, поскольку я использовал список со смесью компонентов упорядоченного списка и неупорядоченных списков. content: no-close-quote кажется странным добавить, я знаю, но это работает ...

ol ul li:before {
    content: no-close-quote;
    counter-increment: none;
    display: list-item;
    margin-right: 100%;
    position: absolute;
    right: 10px;
}
benjarlett
источник
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/ с более обоснованным текстом

Вилли Вонка
источник
Трата времени, чтобы посмотреть. Почти идентичен более раннему ответу. Разница только в том, что ")" был добавлен в конец маркера.
Хуанитоган
0

это правильный код, если вы хотите сначала изменить размер другого 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>
Сандип Кумар
источник