Css последовательность применения правил. Приоритеты стилей в CSS

В данной главе подробно объясняется, почему каскадные таблицы стилей (Cascading Style Sheets, CSS) называются каскадными. Для начала давайте вспомним, какими способами можно добавить стиль на веб-страницу:

  • подключить внешнюю таблицу стилей;
  • добавить внутреннюю таблицу стилей в HTML-документ через тег . В итоге цвет тегов

    Будет красным.

    Это – один из способов управлять значимостью стилей. Еще один способ повысить приоритет – специально увеличить вес селектора, например, добавив к нему ID или класс.

    Объявление!important

    Если вы столкнулись с экстренным случаем и вам необходимо повысить значимость какого-либо свойства, можно добавить к нему объявление!important:

    P {color: red !important;} p {color: green;}

    Также!important перекрывает inline-стили. Слишком частое применение!important не приветствуется многими разработчиками. В основном, данное объявление принято использовать лишь тогда, когда конфликт стилей нельзя победить иными способами.

    Сброс стилей с помощью reset.css

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

    Каждый браузер имеет свои отличия во встроенных стилях: например, в IE нет отступа от верхнего края окна, а в Firefox есть. Таких отличий существует много. Чтобы они не создавали помех для кроссбраузерности при написании собственного стиля CSS, можно воспользоваться методом сброса встроенных стилей.

    Инструмент для сброса стилей – это, по сути, та же самая таблица CSS, где описаны правила, которые сбрасывают встроенные стили браузеров, устанавливая базовые значения свойств. Называется такая таблица reset.css и служит для того, чтобы вы могли начать создавать стиль «с нуля». Вот пример стандартной таблицы сброса:

    Html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video { margin: 0; padding: 0; border: 0; font-size: 100%; font: inherit; vertical-align: baseline; } /* HTML5 display-role reset for older browsers */ article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { display: block; } body { line-height: 1; } ol, ul { list-style: none; } blockquote, q { quotes: none; } blockquote:before, blockquote:after, q:before, q:after { content: ""; content: none; } table { border-collapse: collapse; border-spacing: 0; }

    Любой профессионал своего дела должен владеть терминологией. Если Вы занимаетесь версткой, можете ли без раздумий ответить на вопрос в заголовке статьи?

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

    Наследование

    Начнем с самой простой для понимания концепции CSS. Суть ее состоит в том, что стили, присвоенные некоторому элементу, наследуются всеми потомками (вложенными элементами), если они не переопределены явно. Например, размер шрифта и его цвет достаточно применить к дескриптору body чтобы все элементы внутри имели те же свойства. Но, для заголовков h1-h6 размер шрифта не будет присвоен, потому что у браузера для них есть своя таблица стилей по умолчанию, а наследованные стили имеют самый низкий приоритет. Аналогичная ситуация с цветом ссылок.

    Таким образом, наследование позволяет сократить таблицу CSS. Но в то же время если стилей много, то отследить какой родительский элемент установил некоторое свойство, становится довольно сложно.

    Каскадирование

    Правила каскадирования позволяют разрешать ситуации, когда для одного элемента прописано несколько стилей. Каскадирование основано на присвоении некоторого приоритета каждому правилу. Авторские таблицы стилей имеют самый большой приоритет, меньший — пользовательские, самый низкий — таблицы стилей по умолчанию браузера. У пользователя есть возможность переопределить авторское правило путем добавления флага!important к своему.

    Правила каскадирования определяют следующие приоритеты:

    1. пользовательские стили, отмеченные!important
    2. авторские стили, отмеченные!important
    3. авторские стили
    4. пользовательские стили
    5. стили по умолчанию

    После каскадирования правила упорядочиваются на основе специфичности селекторов.

    Специфичность

    Специфичность — это некоторое число в системе с неопределенно высоким основанием, которое является отражением приоритета какого-либо правила. Вычисляется оно на основе специфичности каждого из селекторов, входящих в правило CSS.

    Специфичность селектора разбивается на 4 группы — a b c d:

    • если стиль встроенный, т.е. определен как style="", то а=1
    • значение b равно количеству селекторов идентификаторов
    • значение c равно количеству классов, псевдоклассов и селекторов атрибутов
    • значение d равно количеству селекторов типов

    Пример вычисления специфичности:

    Селектор Специфичность Специфичность в системе
    с основанием 10
    Style="" 1,0,0,0 1000
    #wrapper #content {} 0,2,0,0 200
    #content .datePosted {} 0,1,1,0 110
    div#content {} 0,1,0,1 101
    #content {} 0,1,0,0 100
    p.comment .datePosted {} 0,0,2,1 21
    p.comment {} 0,0,1,1 11
    div p {} 0,0,0,2 2
    p {} 0,0,0,1 1

    Неопределенно высокое основание системы счисления является следствием того, что неизвестно заранее, насколько большими будут числа a, b, c, d. Если они меньше 10, то удобно использовать десятичную СС.

    Ближе к двум часам ночи в голову в месте с мыслями о вечном приходят не менее вечные вопросы - «в чём смысл жизни?», «зачем вообще человеку спать?» или «Какого чёрта эта #%^$ не работает?» и чем ближе утро, тем сильнее начинает волновать именно этот самый последний вопрос.

    Чуть ниже я расскажу о том какого чёрта сss селекторы иногда не ведут себя так, как нам кажется правильным, и о том как они на самом деле должны себя вести.

    Глава один – идём направо!

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

    Итак, взвешиваем - сначала представим пару рядов из 8 чисел:

    0,1,0,0,0,0,0,0
    1,0,0,0,0,0,0,0

    Знакомьтесь - так в числах выглядят некоторые два селектора, чтобы никто ни о чем не догадался назову их условно «верхний» и «нижний»

    Чтобы узнать какой из них тяжелее, нужно выполнить следующие действия и ничего не перепутать:

    1. Смотрим на крайние левые числа
    2. Выбираем из них большее. - именно этот селектор и будет самым тяжелым
    3. Если числа одинаковые, сдвигаемся на число вправо и повторяем инструкции из пункта 2.
    4. Если все числа одинаковые то применяются стили из селектора который был объявлен последним

    Самая страшная тайна

    Если вы это прочитаете, от вас навсегда уйдет душевный покой, но по крайней мере вы сможете спать по ночам.

    Раскрывая самую страшную тайну я расскажу, как собственно превратить обычный селектор в такие понятные и красивые цифры? Всё как всегда очень просто:

    1. Теги. за каждый тег в селекторе можно накинуть в самое правое число единичку:

      A – это 0,0,0,0,0,0,0,1 div a – это 0,0,0,0,0,0,0,2

    2. Классы , за каждый класс или псевдокласс в селекторе можно накинуть по единичке во второе число справа

      Head .logo – это 0,0,0,0,0,0,2,0 .logo.big – 0,0,0,0,0,0,2,0 div:first-child – 0,0,0,0,0,0,1,1 .logog > .big – и это тоже 0,0,0,0,0,0,2,0
      Да, вы все верно поняли. Css селектор плевать хотел на все эти ваши изыски типа пробелов или «>».

    3. За каждый ID в селекторе добавляем по единичке в третье справа число.

      #head – это 0,0,0,0,0,1,0,0 #head #logo – тоже 0,0,0,0,0,2,0,0

    Я думаю суть вы уловили, теперь можно приступать к небольшой викторине, чтобы это проверить:

    Викторина


    Вопрос: Какого цвета бэкграунд будет в абзаце?
    Ответ: Правильно, красного, потому что селектор не волнует что вам там кажется, и расстояние между тэгами его не интересует. А так как вес тэгов равен – применится последний.

    ?

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

    ?

    Вопрос: Все тот же.
    Ответ: А ответ, для разнообразия другой: наш див будет серым. Потому что как я уже упоминал выше селектору абсолютно безразлично что вы там имели ввиду. У первого селектора вес больше, и никого не волнует что скорее всего ожидали вы не такого поведения.

    Продолжаем раскрывать секреты

    У нас осталось еще так много чисел, и наверняка так хочется узнать что же все они значат – продолжаем раскрывать секреты.
    1. Селектор * абсолютно невесомый, то есть совсем.
    2. Селектор атрибутов это самый обычный псевдокласс и весит он столько же сколько и обычные классы
    3. Любой инлайновый стиль написанный в атрибуте style=”” элемента автоматически получает приоритет0,0,0,0,1,0,0,0 , что сразу делает его очень крутым.
    4. А следующие четыре цифры это все наши старые знакомые только с атрибутом !important

      Div { background-color: gray !important; } Имеет вес при определении свойства background-color - 0,0,0,1,0,0,0,0 .header { background-color: gray !important; } 0,0,1,0,0,0,0,0

    Все мы любим викторины

    ?

Вопрос: Какого цвета будет знак вопроса в ссылке?
Ответ: Красного, неважно что селектор на точное совпадение атрибута выглядит более специфичным, чем селектор который выбирает все что «начинается с». Вес они имеют одинаковый.

?

Вопрос: Мой оригинальный запатентованный вопрос.
Ответ: !important круче всего, даже круче чем инлайн стили – так что бам-бам-бам – серого!

Исходники всех тестов лежат

В больших проектах при разрастании CSS файлов получается не очень радостная ситуация. Из-за большого количества правил возникает трудность с тем, чтобы определить, какие стили должны быть применены к конкретному элементу. Какие-то стили наследуется, что-то определено через целую цепочку всевозможных селекторов, где-то используется .class , где-то #id , а где-то вообще inline-style .

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

  1. Никогда не использовать ID селекторы в CSS . У них нет никаких преимуществ по сравнению с class .
    • Все, что можно сделать с ID , можно сделать и с class .
    • ID не могут быть переиспользованны.
    • Вес ID очень большой. Перебить ID нельзя даже сотней цепных class-ов .
  2. Не создавайте излишних селекторов. Если .header-nav {} прекрасно работает, то не используйте определение .header .header-nav {} . В этом случае ничего не изменится и никакой выгоды от этого не будет.
  3. Не конкретизируйте селекторы, пока это действительно не понадобится. Если .nav {} работает, то не используйте ul.nav {} . Такая запись лишь сократит варианты использования данного класса .nav , а так же повысит вес селектора без очевидной пользы.
  4. Заставьте себя использовать .class , потому что это идеальные селекторы.

Никогда не используйте селекторы тяжелее, чем это необходимо.

Это все очень простые правила и следовать им не так-то трудно.

Уменьшение веса ID

Предположим у вас есть виджет на странице и вы хотите его стилизовать:

...

И, например, мы не можем изменять HTML код виджета, чтобы избавиться от ID. Поэтому мы делаем так:

#widget { ... }

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

{ ... }

Это селектор атрибута. В данном случае это уже определение не для ID , а для элемента. Если говорить точно, то селектор говорит: «Эй, найди мне элемент, у которого есть атрибут id со значением widget ».

Прелесть такого подхода в том, что мы снизили вес ID до веса класса. Но это хак.

Безопасное увеличение веса

Увеличить вес селектора мы можем так:

Btn.btn.btn.btn { ... }

Но я надеюсь, что никогда не придется использовать такую запись на проектах.

Здесь мы видим, что цвет, заданный в .box a {} , перетирает цвет текста кнопки. В итоге текст сливается с фоном кнопки.

Конечно, мы можем исправить это, если поставим !important (jsfiddle.net/csswizardry/3N53n/1), но нет, спасибо, избавимся от этого!

Мы можем добавить дополнительный селектор в секцию .btn {} (23 строка) jsfiddle.net/csswizardry/3N53n/2 , но это не самое лучшее решение. Что, если проблема с кнопкой будет не только в .box , а где-либо еще? Каждый раз добавлять новый селектор – плохой вариант.

Поэтому мы продублируем .btn.btn : http://jsfiddle.net/csswizardry/3N53n/3

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

Теперь мы знаем 2 способа изменения веса селектора, но помните, что все же это хаки и не стоит ими сильно увлекаться.

Элемент HTML может быть целью нескольких правил CSS . Давайте воспользуемся простым абзацем в качестве примера:

Мы можем изменить этот абзац просто используя имя тега :

P { color: blue; }

Или же можем воспользоваться именем класса :

Message { color: green; }

Или можем использовать идентификатор :

#introduction { color: red; }

Поскольку браузер может выбрать только один цвет и применить его к этому абзацу, то он должен решить, какое правило CSS имеет приоритет над другими. Это называется приоритетом в CSS (или специфичностью ).

В нашем примере абзац будет красным , потому что идентификатор более специфичен и, таким образом, более важен , чем другие селекторы.

Порядок правил CSS

Если в вашем CSS есть одинаковые селекторы, то последний из них будет иметь приоритет.

P { color: green; } p { color: red; } /* Абзац будет красным */

Вычисление 100

Есть один быстрый способ выяснить, насколько правило CSS «сильное», путём вычисления специфичности селекторов :

  • идентификаторы стоят 100;
  • классы стоят 10;
  • селекторы тега стоят 1.

Селектор с наивысшим «счётом» будет преобладать, независимо от порядка, в котором появляются правила CSS .

#introduction { color: red; } .message { color: green; } p { color: blue; }

MarkSheet - это бесплатное руководство по HTML и CSS.

Правило #introduction { color: red; } является более специфичным , чем другие, потому что идентификаторы должны быть уникальными по всей веб-странице, таким образом, может быть только один целевой элемент.

Message { color: green; } будет нацелен на любой HTML-элемент с атрибутом class="message" и, следовательно, менее специфичен. То же самое относится и к p { color: blue; } , который может предназначаться для любого абзаца.

Как избежать конфликтов

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

Чтобы избежать этого:

  • применяйте только классы : используйте .introduction вместо #introduction , даже если этот элемент появляется на вашей веб-странице только один раз;
  • избегайте применять несколько классов к одному элементу HTML: пишите не

    А

    Который является семантически более описательным;

  • не используйте встроенные стили , такие как
    .