CSS counters


    Одной из редко используемых возможностей CSS2.1 являются счетчики. Описаны они в разделе спецификации, посвященной генерации контента. Что же это такое?

    Приведу пример из спецификации, эмулирующий обычный нумерованый список с помощью счетчика и свойства content:
    OL { counter-reset: item }
    LI { display: block }
    LI:before { content: counter(item) ". "; counter-increment: item }
    

    Первым правилом мы назначаем элементам OL счетчик с именем «item», затем для всех LI меняем значение свойства display на block, вместо значения по умолчанию (list-item), чем отключаем стандартные маркеры-цифры. Наконец, в последнем правиле, мы инкрементируем счетчик для каждого элемента списка, а само его значение показываем перед элементом c помощью функции counter() и свойства content. Всё просто.


    С помощью механизма счетчиков можно делать нумерованые списки, с нумерацией 1, 1.1, 1.2. Причем сами маркеры можно оформлять достаточно гибко например в результате вот такого кода:
    <style>
    OL { counter-reset: item }
    LI { display: block }
    LI:before { content: "{" counters(item, ".") "} "; counter-increment: item; font-weight:bold }
    </style>

    <ol>
        <li>item 1, level 1</li>
        <li>item 2, level 1</li>
        <li>item 3, level 1</li>
        <li>item 4, level 1
            <ol>
                <li>item 1, level 2</li>
                <li>item 2, level 2</li>
                <li>item 3, level 2</li>
            </ol>
        </li>
        <li>item 5, level 1</li>
    </ol>


    * This source code was highlighted with Source Code Highlighter.

    мы получим вот такой список:



    Функция counters() принимает два параметра, имя счетчика, значение которого нужно вывести и строку-разделитель между значениями вложенных счетчиков, в данном случае это точка. Также вторым параметром можно указывать любое из возможных значений атррибута list-style-type, т.е. none, disc, circle и square. В последних трех случаях список станет выглядеть так же как обычный ненумерованный список с маркерами соответствующего типа.

    Но и это еще не всё


    С помощью счетчиков можно реализовать то, что совсем недавно делалось исключительно с помощью скриптов — считать элементы, и выводить результат подсчета на странице. Например результатом такого кода:
    <style>
        div {counter-reset: num-p} /* объявляем счетчик num-p */
        div p {counter-increment: num-p;margin:0} /* для каждого p внутри div инкрементируем его */
        div:after {    /* выводим результат */
            display:block;font-weight:bold;
            content: "Всего абзацев: " counter(num-p)    ".";
        }
    </style>
    <div>
        <p>Абзац 1</p>
        <p>Абзац 2</p>
        <p>Абзац 3</p>
        <p>Абзац 4</p>
    </div>


    * This source code was highlighted with Source Code Highlighter.

    станет вот такая страница:



    Здесь мы воспользовались псевдоэлементом :after элемента div, для вывода конечного значения привязанного к нему счетчика.

    Ну и наконец приведу код, результат которого вы видели на изображении в самом начале топика, если вы подключите этот стиль в качестве пользовательского стиля вашего браузера, то возле каждого топика у вас появится «немного статистики» о нем:

        /* Инициализируем счетчики */
        div.hentry {
            counter-reset:
                num-post-sections 1
                    /* Количество заголовков/секций в топике. Обратите внимание, что счетчику можно передать начальное значение. */
                    /* В данном случае это единица, потому что один заголовок уже есть вне блока .content */
                num-code-listings  /* Листинги кода code и pre */
                num-bq             /* цитаты */
                num-br             /* break-lines */
                num-links          /* ссылки */
                num-links-internal /* внутренние ссылки */
                num-links-rel-tag  /* ссылки тэгов rel='tag' */
                num-img             /* изображения */
            ;
        }
        /* Инкрементируем счетчики. */
        div.hentry .content h4,
        div.hentry .content h5,
        div.hentry .content h6 { counter-increment: num-post-sections; }
        div.hentry .content code,
        div.hentry .content pre { counter-increment: num-code-listings; }
        div.hentry .content img { counter-increment: num-img; }
        div.hentry .content blockquote { counter-increment: num-bq; }
        div.hentry .content br { counter-increment: num-br; }
        
        div.hentry .content a[href] {     /* все ссыкли */
                counter-increment: num-links;
        }
        div.hentry .content a[href^="http://habrahabr.ru/"],
        div.hentry .content a[href^="/"] { /* внутренние ссыкли */
                counter-increment:
                    num-links
                    num-links-internal;
        }
        div.hentry a[rel="tag"] { /* теги */
                counter-increment:
                    num-links
                    num-links-rel-tag;
        }
        /* Показываем результат счетчиков */
        div.hentry:after {
            clear:both;
            display: block;
            background:#9cc;
            border:1px solid #79B1D4;
            padding:10px;
            margin:0 35px;
            white-space:pre;
            content:
                "This topic contains: \a"
                "Sections - " counter(num-post-sections) ",\a"
                "Code listings - " counter(num-code-listings) ",\a"
                "Links - " counter(num-links) ", " counter(num-links-internal) " internal and "
                counter(num-links-rel-tag)" tags, \a"
                "Images - " counter(num-img) ",\a"
                "Quotes - " counter(num-bq) ",\a"
                "Break lines - " counter(num-br) "\a"
            ;
        }


    * This source code was highlighted with Source Code Highlighter.


    Ограничения


    1. К сожалению, всеми нами горячо и страстно любимый браузер Intenet Explorer — не поддерживает CSS-счетчики вплоть до версии 7, как и свойство content. Но в 8-й, говорят поддержка будет.
    2. Вывод суммарных счетчиков возможен только в псевдоэлементе :after, что ограничивает возможности дизайна.
    3. Контент, сгенеренный с помощью css не может быть выбран/выделен пользователем.

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

    Upd. В написании топика и кода сильно помогла статья Meitar Moscovitz, там есть еще неплохие примеры.
    Метки:
    Поделиться публикацией
    Реклама помогает поддерживать и развивать наши сервисы

    Подробнее
    Реклама
    Комментарии 27
    • +2
      хочу if, for и goto в css, а не эти убогие хаки! =)
      • НЛО прилетело и опубликовало эту надпись здесь
        • +1
          да! да! да! будем делать поддержку любых css-свойств, не дожидаясь появления браузеров их поддерживающих! =)
          • НЛО прилетело и опубликовало эту надпись здесь
            • –1
              IE как всегда не будет поддерживать эту возможность.
              • +2
                В IE8 будет.
                • 0
                  >IE как всегда не будет поддерживать эту возможность.
                  IE поддерживал expression и behavior. И это очень многим н нравилось.
              • 0
                а чем XSLT не нравится?
                • НЛО прилетело и опубликовало эту надпись здесь
                • +13
                  а я хочу спать
                  • 0
                    Сейчас работаю верстальщиком. Мне все это близко. Вот столько возможностей даёт CSS 2.1 и 3, прям не могу нарадоваться, но сираны IE всё портит.
                    Поэтому, я всем, кому только могу, устанавливаю FF на компы, с ведома человека или даже без. Так сказать приближаю момент всеобщей эйфории.
                    • 0
                      Я тоже так делаю, но далеко не все этому рады, как я =)) Большинство банально не хочет переучиваться. Говорят, мол сложно… А когда попробуют, то понимают, что ничего сложного…
                      • +7
                        это из разряда приближения весны путем поедания снега :)
                        • 0
                          Совсем нет =) Просто надо ставить FF «незаметно». Снаружи он как IE выглядит, если все необходимое сделать. Где-то на хабре даже статейка была про это.
                          Юзер просто не замечает что что-то поменялось =)
                          • 0
                            пользуйтесь лучше концепцией прогрессивного улучшения — он неё больше толку, чем от таких ваших небольших «диверсий». И для вас, и для общего дела борьбы с устаревшими браузерами :-)
                            • 0
                              Использую.
                              Но людей приучать к хорошему все равно не перестану :)
                            • 0
                              Действительно, школа юного диверсанта какая-то.

                              А пока остается работать с тем что есть и надеяться на то, что антимонопольный процесс против MS заставит их с большим уважением относиться как к пользователям так и разработчикам.

                              p.s. На хабре случаем статейки нет, как юзера из под винды на Linux «незаметно» перевести? Очень нужно.
                        • 0
                          Вау. спс порадовали и не только статьей ;)
                          • 0
                            Не забываем указывать первоисточники, а то люди могут подумать о вас плохо.

                            www.sitepoint.com/blogs/2009/01/06/a-little-known-way-to-replace-some-scripts-with-css-counters/
                            • +1
                              Ну вообще то источником ее можно назвать с большой натяжкой, различий гораздо больше чем общего, в том числе и код разный и примеры, если присмотрется, да и общее есть, благодаря микроформатам. Так что думать обо мне плохо не надо :)

                              Но впрочем вы правы, упомянуть стоит.
                            • –2
                              ай ай
                              • +3
                                На js, канешно, такое попривычнее видеть… Да и правильнее наверно на нем это делать(по крайней мере в наше время с устаревшими браузерами). Ведь стили по идеологии должны отвечать за визуальное оформление. Но посмотрим как оно все дальше будет развиваться))
                                • 0
                                  Ещё счётчики удобно использовать, чтобы получать таблички со строками разных цветов (строка тёмная, строка светлая). Даже можно несколько цветов использовать, хотя с двумя и попривычнее.
                                  • +1
                                    Для этого уже :nth-child() придумали :-)
                                    • 0
                                      Я путаю, или среди браузеров шире поддержка счётчиков, чем :nth-child()?

                                      Хотя соглашусь с :hth-child() гораздо удобнее.
                                      • 0
                                        Да, поддержка счетчиков действительно шире.
                                        Но пока нет полной поддержки всеми актуальными браузерами хотя бы чего-то одного, думаю, на практике всерьез задумываться о применении рановато…
                                  • 0
                                    сорри за оффтопик, а что за шрифт на скрине?

                                    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.