CSS counter-reset по вложенному списку


Я борюсь с counter-reset, когда ол находится в div. Красный список в сниппете нумерации должен быть:

1, 2, 3

Не:

[3]}3.1, 3.2, 3.3,

ol {
    counter-reset: item;
    list-style: none;
}
li:before {
    counter-increment: item;
    content: counters(item, ".")" ";
}
<ol>
    <li>BBD</li>
    <li>BBD
        <ol>
            <li>BBD</li>
            <li>BBD</li>
            <li>BBD</li>
        </ol>
    </li>
    <li>BBD</li>
</ol>

<ol>
    <li>BBD</li>
    <li>BBD</li>
    <li>BBD</li>
</ol>

<div>
    <ol style="color:red;">
        <li>BBD</li>
        <li>BBD</li>
        <li>BBD</li>
    </ol>
</div>

Http://jsfiddle.net/1dab8xs7/1/

3 9

3 ответа:

Ваша проблема не со свойством counter-reset, а со свойством content и функцией counters(). Эта функция автоматически добавляет новый экземпляр для каждого вложенного элемента. Это отлично подходит для вложенных элементов ol, но также добавляет экземпляр счетчика, когда первый Уровень ol вложен в любой другой элемент.

Таким образом, вы должны использовать функцию counter() на элементах первого уровня ol и сохранить функцию counters() (Обратите внимание на "s") на втором уровне:

Подробнее MDN о счетчиках вложенности

ol {
    counter-reset: item;
    list-style: none;
}
li:before {
    counter-increment: item;
    content: counter(item)". ";
}
ol ol li:before{
  content: counters(item,".") " ";
}
<ol>
    <li>BBD</li>
    <li>BBD
        <ol>
            <li>BBD</li>
            <li>BBD</li>
            <li>BBD</li>
        </ol>
    </li>
    <li>BBD</li>
</ol>

<ol>
    <li>BBD</li>
    <li>BBD</li>
    <li>BBD</li>
</ol>

<div>
    <ol style="color:red;">
        <li>BBD</li>
        <li>BBD</li>
        <li>BBD</li>
    </ol>
</div>

Как предлагает @harry , вы также можете установить сброс счетчика на первом потомке элемента ol, либо с псевдоклассом li:first-child, либо с псевдоэлементом ol::before, например:

ol{
    list-style: none;
}
li:first-child{
    counter-reset: item;
}
/* or
ol:before {
    content: '';
    counter-reset: item;
}
*/
li:before {
    counter-increment: item;
    content: counters(item, ".")" ";
}
<ol>
    <li>BBD</li>
    <li>BBD
        <ol>
            <li>BBD</li>
            <li>BBD</li>
            <li>BBD</li>
        </ol>
    </li>
    <li>BBD</li>
</ol>

<ol>
    <li>BBD</li>
    <li>BBD</li>
    <li>BBD</li>
</ol>

<div>
    <ol style="color:red;">
        <li>BBD</li>
        <li>BBD</li>
        <li>BBD</li>
    </ol>
</div>

Вы должны сбросить div
И "не сбросить" ol
Вот так:

<div style="color:red;counter-reset: item;">
    <ol style="color:red;counter-reset: none;" id="test">
        <li>BBD</li>
        <li>BBD</li>
        <li>BBD</li>
    </ol>
</div>

Один из способов обойти эту проблему-добавить класс (поскольку вы не можете выбрать элемент на основе того, что является его родителем) и исключить его из первоначального выбора с помощью псевдокласса :not:

HTML:

<ol>
    <li>BBD</li>
    <li>BBD
        <ol>
            <li>BBD</li>
            <li>BBD</li>
            <li>BBD</li>
        </ol>
    </li>
    <li>BBD</li>
</ol>

<ol>
    <li>BBD</li>
    <li>BBD</li>
    <li>BBD</li>
</ol>

<div>
    <ol class="x" style="color:red;">
        <li>BBD</li>
        <li>BBD</li>
        <li>BBD</li>
    </ol>
</div>   

CSS:

ol:not(.x) {
    counter-reset: item;
    list-style: none;
}
ol:not(.x) li:before {
    counter-increment: item;
    content: counters(item, ".")" ";
}   

Согласно этому JSFiddle