Support us

CSS. Специфичность и Наследование

Оставить комментарий
CSS. Специфичность и Наследование
Порог вхождения в CSS совсем невысок, прежде всего в силу самой природы его синтаксиса, прозрачного и лёгкого для понимания даже неопытному веб-дизайнеру. Это так просто, что на самом деле вы сможете закодить простенький сайт на CSS буквально после несколько часов изучения каскадных таблиц стилей. Но эта кажущаяся простота обманчива. После нескольких часов работы ваш идеально составленный сайт отлично смотрится в Safari, но всё идёт прахом, если вы не приняли необходимые меры заранее, чтобы всё работало нормально и в Internet Explorer. В панике вы добавляете кучу хаков и фильтров туда, где достаточно было только поправить несколько настроек или просто использовать другой подход. Знание того, как решать эти вопросы, приходит с опытом и с шишками, набитыми методом проб и ошибок, а также провалами, которые и выводят на правильный путь изучения CSS. Понимание некоторых концепций, которые на первый взгляд достаточно сложны для восприятия и выглядят на редкость скучными, крайне важно для дальнейшего использования. Но многие просто не уделяют их осмыслению достаточного внимания, что часто и является корнем всех проблем при их использовании. Две подобные концепции – это специфичность и наследование. Не очень часто встречающиеся слова в лексиконе веб-дизайнеров, не так ли? Рассуждать о border-radius и text-shadow куда интереснее и веселее, но специфичность и наследование – это фундаментальные базовые понятия, которые каждый, кто претендует на право зваться специалистом по CSS, должен чётко представлять. Понимание этих концепций поможет вам создавать чистые, удобные в поддержке и гибкие таблицы стилей. Давайте посмотрим на то, что они означают и как они работают. Понятие "Каскадирование" – самое что ни на есть сердце CSS. Оно, в конечном счете, определяет, какие свойства будет изменять данный элемент. Каскад связан с тремя основными концепциями: происхождение, приоритет и специфичность. Каскадирование CSS проходит через эти три шага-правила, чтобы определить, какие свойства назначить элементу. К концу этого процесса каскадом будет назначен вес для каждого правила, и этот вес определяет, какое правило имеет преимущество в случае наличия конкуренции.

Происхождение и приоритет

Таблицы стилей могут иметь несколько источников происхождения:
  1. User agent
    • Например, дефолтный стиль браузера
  2. User
    • Стиль, указанный пользователем в настройках браузера
  3. Author
    • Авторский стиль, указываемый автором странички (внешний, встроенный или inline-стиль, когда в HTML-документе информация стиля для одного элемента указывается в его атрибуте style)
По умолчанию есть порядок, в котором стили из различных источников обрабатываются – так, правила автора переопределяют пользовательские и браузерные и т.д. Существует также конструкция приоритета !important, которая используется для приведения к балансу использования пользовательских и авторских таблиц стилей. В то время как авторская таблица стилей по умолчанию имеет преимущество над другими, пользовательское правило, объявленное с конструкцией !importan, будет переопределять даже авторское с такой же конструкцией. Зная об этом, давайте посмотрим на окончательный список, в порядке возрастания значимости по приоритету и происхождению:
  1. User agent объявления,
  2. Пользовательские объявления,
  3. Авторские объявления,
  4. Aвторские объявления с конструкцией !important,
  5. Пользовательские объявления с конструкцией !important.
Такая гибкость в плане приоритетов является ключевой в каскадных таблицах стилей, поскольку она позволяет пользователям переопределять стили, которые могли бы препятствовать доступности веб-сайта. (Пользователю может требоваться более крупный шрифт или другой цвет текста, например.)

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

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

Как рассчитывать специфичность?

Если несколько методов расчёта специфичности селекторов. Наиболее быстрый способ заключается в следующем: Добавить 1 к каждому элементу или псевдоэлементу (например, :before и :after ); добавить 10 каждому атрибуту (например [type=”text”]), классу или псевдоклассу (:link или :hover); добавить 100 для каждого ID, а к inline стилю добавить 1000. Давайте подсчитаем специфичность следующих селекторов, используя данный метод:
p.note - 1 класс + 1 элемент = 11
#sidebar p[lang="en"] - 1 ID + 1 атрибут + 1 элемент = 111
body #main .post ul li:last-child - 1 ID + 1 класс + 1 псевдокласс + 3 элемента = 123
Аналогичный метод, описанный в спецификации W3C, предлагает нам начинать с оценки специфичности как нулевой (в числе abcd каждый разряд нулевой a = 0, b = 0, c = 0 и d = 0) и заменять цифры согласно наличию у селектора элементов, атрибутов и т.д.):
  • a = 1, если inline стиль,
  • b = количество удостоверений,
  • c= число атрибутов селекторов, классов и псевдоклассов,
  • d = количество имен элементов и псевдоэлементов.
Давайте подсчитаем специфичность следующего набора селекторов:

  • a=1, b=0, c=0, d=0 → 1000
    footer nav li:last-child
  • a=0, b=0, c=1, d=3 → 0013
    #sidebar input:not([type="submit"])
  • a=0, b=1, c=1, d=1 → 0111
Помните, что не-CSS презентационной разметке присуждается значение специфичности ноль, применяться это будет, к примеру, для тэга font. Возвращаясь к конструкции !important, не забывайте, что использование данного приоритета для сокращённых свойств автоматически придаёт его и всем подсвойствам, даже если это возвращает им изначальные значения. Если вы используете импортируемые таблицы стилей в CSS (@import), вы должны объявлять их перед всеми остальными правилами, чтобы они считались, таким образом, предшествующими всем правилам CSS файла.

Как заставить специфичность работать на вас

Если невнимательно следить за специфичностью, то она может привести вас к созданию вместо грамотной таблицы стилей чего-то малопонятного с массивной иерархической структурой ненужных и слишком сложных правил. Чтобы избегать этого, стоит не забывать об основных правилах работы со специфичностью:
  • Когда начинаем работу над CSS, использовать общие селекторы и добавить конкретики по ходу работы и её уточнения
  • Использование сложных селекторов не означает необходимости максимального их усложнения
  • Полагаться стоит больше на специфичность, нежели на порядок следования селекторов, так ваши таблицы стилей будут более удобными для редактирования и поддержки (особенно людям со стороны).
Рефакторинг CSS селекторов, менее специфичных в экспоненциальной степени, сложнее, чем просто добавление специфичных правил по мере возникновения ситуаций.

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

Наследование является способом распространения значения свойств элементов от родителей к детям. Некоторые свойства CSS наследуются детьми элементов по умолчанию. Например, если вы установите body тегу страницы конкретный шрифт,то шрифт будет наследоваться другими элементами, например, заголовками и абзацами, не требуя соответствующей прописки каждый раз. CSS спецификация определяет, в каких случаях наследование каждого свойства идёт по умолчанию. Не все свойства наследуются, но мы можем заставить какие-то свойства наследоваться посредством присвоения значения inherit. Хотя это несколько выходит за рамки данной статьи, всё-таки необходимо упомянуть, что наследование в CSS не стоит путать с наследованием в объектно-ориентированном программировании (ООП). Вот как выглядит определение ООП наследования от Википедии, что и уточняет, что речь не идет об одном и том же: В объектно-ориентированном программировании (ООП) наследование является способом формирования новых классов [...] с помощью классов, которые уже были определены. Наследование используется, чтобы помочь использовать существующий код с минимальными изменениями. Новые [классы ...] наследуют атрибуты и поведение уже существующих классов. ...

Как работает наследование?

Когда элемент наследует значение от своего предка, он наследует его вычисленное значение. Что это означает? Каждое свойство в CSS проходит через четырёхступенчатый процесс определения значения. Вот цитата из W3C спецификации: Окончательное значение свойства является результатом четырёхступенчатого вычисления: значение определённое спецификацией (специфицированное значение), затем разрешается в значение, используемое для наследования (вычисленное значение), которое при необходимости конвертируется в абсолютное значение, и уже окончательно трансформируется в значение, соответствующее ограничениям локальной среды ("реальное значение"). Иначе говоря:
  1. Специфицированное значение.
  2. User agent (инструмент пользователя, тот же браузер) определяет, откуда должно использоваться значение для свойства – из таблицы стилей, оно наследуется или же имеет свой первоначальный вид.
  3. Вычисленное значение.
  4. Специфицированное значение разрешается в вычисленное значение и существует, даже когда свойство не применяется. Документ не должен верстаться, чтобы данное значение было определено.
  5. Используемое значение.
  6. Используемое значение берёт расчетное значение и разрешает с ним все зависимости, которые могут быть рассчитаны только после
  7. Действительное значение.
  8. Это значение используется для окончательного рендеринга, после применения каких-либо приближений (например, преобразование десятичных чисел в целое).
Если вы посмотрите спецификацию какого-либо CSS свойства, то увидите, что она описывает его первоначальное значение (дефолтное), элементы к которым оно применяется, статус наследование и его вычисленное значение (среди других). Например, спецификация свойства цвета заливки фона (background-color) выглядит следующим образом:
Name: background-color
    Value: 
    Initial: transparent
    Applies to: all elements
    Inherited: no
    Percentages: N/A
    Media: visual
    Computed value: the computed color(s)
Смущает несколько? Может быть. Итак, что же мы должны понять из всего этого? И почему это имеет отношение к наследству? Давайте обратимся к первому предложению данного раздела, которое сейчас будет нам понятнее. Когда элемент наследует значение от своего предка, он наследует его вычисленное значение. Вычисленное значение существует, даже если его не было в таблице стилей и соответственно даже в таком случае может наследоваться и принимать значение, которое существовало по умолчанию. Таким образом, вы можете использовать наследование, даже если родительский элемент не имел специфицированного конкретного значения.

Использование наследования

Самая главная вещь, которую вы должны знать о наследовании – это его существование и как оно работает. Вообще на самом деле наследование в данном случае совсем простое для понимания. Представьте себе, что вы должны были бы указывать размер шрифта или семейство шрифтов для каждого элемента, а не просто добавить его в body тэг? Это было бы жутко громоздким, и поэтому наследования так полезно. Не разрывайте его, используя универсальный селектор (*) со свойствами, которые наследуются по умолчанию. Вы не должны помнить все наследуемые значения, но в свою очередь вам необходимо о них не забывать. Редко CSS-статья не содержит каких-то плохих новостей о Internet Explorer. Эта статья не является исключением. IE поддерживает наследуют значение только с версии 8, за исключением direction и visibility свойств. Круто.

Использование инструментов

Если вы используете такие инструменты, как Firebug или Safari веб-инспектор, можно увидеть, как данный каскад работает, какие селекторы имеют более высокую специфичность и как наследование работает для конкретного элемента. Вот, например, ниже Firebug в действии, проверка элемента на странице. Вы можете увидеть, что некоторые свойства переопределяются (на скриншоте они зачёркнуты) на другие, более специфичные (конкретные) правила: В следующем скриншоте Safari веб-инспектор показывает расчетные значения элемента. Таким образом, вы можете увидеть значения, даже если они не были четко прописаны в таблице стилей:

Заключение

Даже если вы не особо задумываетесь о них, эти вопросы находятся в вашей повседневной работе как работе человека, занимающегося кодированием CSS. Особенно в случае специфичности важно знать, как она влияет на таблицы стилей и как планировать её так, чтобы она вызывала лишь минимальное количество проблем при кодировании. А лучше, чтобы вообще не вызывала. Оригинальная статья на Smashing Magazine
16 лет dev.by — «дефолтный» источник информации о беларусском ИТ

Вы можете...

Читайте также
Браузерные войны: как менялась расстановка сил последние 28 лет
Браузерные войны: как менялась расстановка сил последние 28 лет
Браузерные войны: как менялась расстановка сил последние 28 лет
«Ты был вишенкой на торте»: Mozilla прислала Microsoft торт по случаю «смерти» Internet Explorer
«Ты был вишенкой на торте»: Mozilla прислала Microsoft торт по случаю «смерти» Internet Explorer
«Ты был вишенкой на торте»: Mozilla прислала Microsoft торт по случаю «смерти» Internet Explorer
В Южной Корее программист похоронил Internet Explorer, поставив ему памятник
В Южной Корее программист похоронил Internet Explorer, поставив ему памятник
В Южной Корее программист похоронил Internet Explorer, поставив ему памятник
Отключение Internet Explorer сильно ударило по японскому бизнесу
Отключение Internet Explorer сильно ударило по японскому бизнесу
Отключение Internet Explorer сильно ударило по японскому бизнесу
6 комментариев

Хотите сообщить важную новость? Пишите в Telegram-бот

Главные события и полезные ссылки в нашем Telegram-канале

Обсуждение
Комментируйте без ограничений

Релоцировались? Теперь вы можете комментировать без верификации аккаунта.

Комментариев пока нет.