добавить внутреннюю таблицу стилей в 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
файлов получается не очень радостная ситуация. Из-за большого количества правил возникает трудность с тем, чтобы определить, какие стили должны быть применены к конкретному элементу. Какие-то стили наследуется, что-то определено через целую цепочку всевозможных селекторов, где-то используется .class
, где-то #id
, а где-то вообще inline-style
.
Чтобы изменить стили для элемента, нам приходится играться с весами селекторов. Чтобы облегчить нашу работу, мы можем следовать нескольким рекомендациям:
- Никогда не использовать ID
селекторы в CSS
. У них нет никаких преимуществ по сравнению с class
.
- Все, что можно сделать с ID
, можно сделать и с class
.
- ID
не могут быть переиспользованны.
- Вес ID
очень большой. Перебить ID
нельзя даже сотней цепных class-ов
.
- Не создавайте излишних селекторов. Если .header-nav {}
прекрасно работает, то не используйте определение .header .header-nav {}
. В этом случае ничего не изменится и никакой выгоды от этого не будет.
- Не конкретизируйте селекторы, пока это действительно не понадобится. Если .nav {}
работает, то не используйте ul.nav {}
. Такая запись лишь сократит варианты использования данного класса .nav
, а так же повысит вес селектора без очевидной пользы.
- Заставьте себя использовать .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 способа изменения веса селектора, но помните, что все же это хаки и не стоит ими сильно увлекаться.
Chris Coyier
Вопрос правильного понимания термина CSS специфичность
и ее роли в веб-разработке зачастую связан с некоторыми трудностями. Наиболее удачным способом освоения этого вопроса является рассмотрение примера, в котором CSS специфичность представлена в наиболее сложной форме и, возможно, противоречит вашим предположениям. В данной статье используется именно такой способ, позволяющий понять принципы вычисления фактического значения специфичности CSS селекторов и определения их приоритетности.
В качестве примера возьмем обычный неупорядоченный список, представляющий три вида напитков:
Теперь, допустим, мы хотим визуально выделить один из напитков, который является наиболее предпочтительным. Для этого нужно предусмотреть соответствующий инструмент – указать имя класса для требуемого элемента списка:
Favorite {
color: olive;
font-weight: bold;
}
Осталось лишь посмотреть на результат работы этого кода. Но увы, мы не получили ожидаемого эффекта – текст выбранного нами напитка (Whiskey
) не будет выделен и отображается также, как и остальные элементы списка. В чем же дело?
Возможной причиной возникшей проблемы может быть другое правило, которое определено в том же CSS
документе, имеющее следующий вид:
ul#drinks li {
color: black;
font-weight: normal;
font-size: 13px;
}
Именно это CSS правило содержит определения, препятствующие визуальному выделению желаемого элемента списка. В используемом документе находится два различных CSS селектора, применяемых к одному элементу (.favorite
и ul#drinks li
), которые предусматривают различные значения для цвета и толщины шрифта, содержащегося в нем текста. Что касается размерности шрифта, то здесь все понятно – рассматриваемый код содержит лишь одно выражение, определяющее его значение ( font-size: 13px
), поэтому именно оно и будет использоваться. Проблема, в данном случае, заключается в том, что браузер должен определить, какому из конфликтующих правил отдать предпочтение в процессе обработки документа. Как раз для этих целей и предназначены значения CSS специфичности каждого из правил.
Большинство проблем возникает у начинающих веб-разработчиков, которые не понимают, по какому принципу производится выбор рабочего правила. Они, как правило, предполагают, что приоритетом должен обладать селектор .favorite
, так как он находится ниже в структуре CSS кода или потому, что определение атрибута class="favorite"
в HTML разметке документа находится ближе к текстовому содержимому интересующего нас элемента страницы (
). Но все это, конечно же, заблуждения.Да, действительно, CSS спецификацией предусмотрено, что положение правила в структуре кода имеет значение. И то из них, которое расположено ниже, действительно обладает приоритетом, но только в том случае, если значения специфичности
рассматриваемых выражений одинаковы. Вот пример:
Favorite {
color: olive;
}
.favorite {
color: black;
}
В этом случае цвет шрифта выбранного элемента списка будет черным (*поскольку последнее правило переопределяет значение первого
). Но мы немного отклонились от темы.
Здесь работает несколько иной принцип. Всякий раз, когда вы формируете селектор для CSS правила, всегда делайте его настолько специфичным (конкретным), насколько это возможно и оправданно.
(*Для этого необходимо применять более сложные селекторы
). При рассмотрении простейшего примера, приведенного выше, вы, вероятно, сами догадались, что использование лишь имени класса .favorite
для селектора, выбирающего требуемый напиток из списка, будет недостаточным. И это не позволит извлечь из общего списка «нужный напиток» для его дальнейшего форматирования. А если это все-таки каким-то образом сработало один раз, то нет никакой гарантии, что в будущем все пройдет так же гладко. Для достижения желаемого результата необходимо использовать более конкретный селектор:
ul#drinks li.favorite {
color: olive;
font-weight: bold;
}
Это именно то, что я называю достаточно конкретизированный селектор
, то есть тот, который в данном случае максимально точно указывает на требуемый элемент и в тоже время является достаточным, не содержащим лишних элементов, без которых можно обойтись. К примеру, вот этот вариант будет уже избыточным, хотя тоже рабочий:
html body div#content ul#dirnks li.favorite {
color: olive;
font-weight: bold;
}
Такой селектор тоже допусти́м, но он слишком «захламляет» CSS код, что значительно снижает его читабельность. К тому же от такой избыточности нет никакого толку. Существует и другой способ «вычленения» требуемого элемента, путем повышения значения CSS специфичности селектора .favorite
при помощи декларации ! important
:
Favorite {
color: olive! important;
font-weight: bold! important;
}
Использование декларации ! important
является универсальным методом задания приоритетности CSS правилам. И с его помощью вы сможете принудительно переопределить назначенные ранее свойства элемента, но этот метод является радикальным и в некоторых случаях его использование не оправданно.
Если использовать ключевое слово ! important
не по назначению, то можно лишь усложнить себе задачу. В том случае, когда вы хорошо знакомы с определенным CSS кодом и знаете, для каких целей используется каждый, содержащийся в нем селектор, то применение декларации ! important
вполне оправдано для упрощения структуры кода и повышения его читабельности. Но если же вы применяете его с целью быстрого переопределения свойств, предусмотренных другим автором, не вникая в структуру кода и принципы его работы, то это может привести к нежелательным последствиям.
Один из классических примеров, которые я использую:
Last-block {
margin-right: 0! important;
}
Я применяю данный класс в тех случаях, когда на странице имеется несколько «плавающих» блоков (*с установленным свойством float
, в данном случае со значением left
), которые размещаются в один ряд. При этом, назначая это имя класса для последнего в ряду блока (самого правого), я полностью исключаю ситуацию, когда он неплотно прилегает к границе контейнера, что в моем случае недопустимо. Даже если где-то в структуре CSS кода, в рамках правила с более специфичным (конкретным) селектором определены другие значения свойства margin-right
для используемых блоков, то применение класса .last-block
к крайним элементам позволит обнулить их. При этом мы не используем никаких дополнительных составляющих селектора, конкретизирующих его, что упрощает представление кода.
Подсчет значения CSS специфичности.
Рассматривая предыдущий пример, мы с вами выяснили, что наша первая попытка определения цвета и жирности шрифта для элемента списка провалилась из-за того, что мы использовали селектор лишь с одним именем класса, который имеет меньшее значение CSS специфичности и был переопределен селектором, выбирающим неупорядоченный список по его идентификатору ID, который имеет большее значение специфичности. Ключевыми значениями в данном случае являются имена классов (class) и идентификаторы элементов (ID). Очень важно знать, что CSS стандарты предусматривают существенные различия в весовых значениях специфичности для селекторов классов class и идентификаторов ID. Селекторы, использующие идентификаторы элементов, имеют безупречное преимущество над теми, в которых применяются лишь имена классов. При любом количестве имен классов в селекторе, он будет переопределен другим селектором, имеющим в своем составе один идентификатор элемента.
Теперь давайте схематически рассмотрим метод определения и записи значений CSS специфичности селекторов:
Другими словами:
- Если в теге элемента предусмотрен атрибут style
, то все определенные в его рамках свойства имеют максимальный приоритет (значение специфичности в этом случае получает высший разряд – 1,0,0,0
).
- Для каждого идентификатора элемента, используемого в рамках селектора прибавляется единица в соответствующий разряд специфичности – 0,1,0,0
.
- Каждое имя класса, а также псевдокласса или селектор атрибута (* element
), присутствующий в селекторе правила добавляет единицу в следующий разряд специфичности – 0,0,1,0
.
- И последний, самый младший разряд, получает по единице за каждое, присутствующее в селекторе имя элемента – 0,0,0,1
.
Вы можете избавиться от запятых и преобразовать значения CSS специфичности в более привычную для вас форму представления значений – обычные числа: 1,0,0,0
можно представить как 1000
, что значительно больше значения 0,1,0,0
или 100
. Используемые в этом случае запятые предназначены для четкого разделения значений различных разрядов специфичности. К примеру, если в CSS селекторе используется 13
имен классов, псевдоклассов и/или селекторов атрибутов (что маловероятно), то значение специфичности в этом случае может принять вид 0,1,13,4
, что невозможно представить в десятичном виде.
* Исчерпывающую информацию по декларации ! important
можно прочесть .
* Примечание переводчика.