Наследование в CSS. Наследование свойств css

Мы продолжаем изучение CSS, мы уже рассмотрели достаточно много свойств и в этом уроке мы немного отдохнем от этого назойливого слова. И перейдем мы к, достаточно интересной теме, - наследованию. Данный метод сильно облегчает использование CSS, поэтому стоит понять, как это все работает и для чего это вообще нужно.

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

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

Думаю мысль Вы поняли, и такая ситуация со всеми элементами. Зачем это все делать? Во-первых, это сокращает Вами написанный код, и код становится более наглядным. Ну, а во-вторых написанный код становится более динамичным, то есть если вы захотите изменить размер шрифта или тип его, то Вам стоит внести изменения только в одном месте и далее текст автоматически унаследует новые значения, и Вам не придется лезть во все свойства, каждого текстового блока, и их менять.

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

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

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

HTML

HTML страница

Заголовок первого уровня

Обычный параграф для примера

  • Список для приммера
  • Список для приммера
  • Список для приммера

Обычный заголовок второго уровня

Обычный параграф для примера

Обычный заголовок третьего уровня

Обычный параграф для примера

Мы создали ряд элементов. Как видно у них нет ни каких стилей, самый обычный текст, который браузер установил по умолчанию.

Теперь нашему родителю тегу зададим свойства: размер, цвет и гарнитуру шрифта и посмотрим его потомки (все теги, которые в него входят) наследуют эти свойства или нет.

HTML

Body{ color: #ff0000; font-size: 20px; font-family: courier new; }

После того, как задали родителю определенные свойства, обновим страницу и наши потомки должны будут унаследовать указанные стили (весь текст красный, размером в 20px с гарнитурой courier new ).

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

И давайте разберем исключения немного подробней.

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

Стоит рассмотреть еще момент, когда не наследуются все свойства, например для тега задать рамку.

HTML

Body{ color: #ff0000; font-size: 20px; font-family: courier new; borde:2px solid #00ff00; }

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

От сюда стало ясно, что есть свойства, которые наследуются, а есть которые нет. Узнать, какие свойства наследуются, какие нет можно посмотрев спецификацию CSS . Там Вы найдете все нужные для Вас свойства и в колонке Inherited? указано наследуется свойство или нет. И если Вы, для интереса, посмотрите свойство border , то там будет установлен статут в NO , то есть не наследовать, в чем мы сами ранее и убедились.

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

11 марта 2014 в 18:23

Инкапсуляция CSS-стилей - Часть 1. Проблема

  • CSS ,
  • HTML

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

В процессе этих трансформаций и миграций выяснилось, что рост трудоемкости создания и поддержания веб-интерфейса значительно опережает рост его сложности. Проблему пытались (и пытаются до сих пор) решить путем разбиения на модули, абстрагирования, инкапсуляции. С этой целю было создано большое количество JavaScript-фреймворков (Backbone , Ember , Angular), HTML-шаблонизаторов (Jade , Handlebars), систем управления зависимостями (RequireJS) и т.п.

Наиболее сложным с этой точки зрения оказался CSS, где по дизайну языка любое свойство, объявленное в любом подключенном CSS-файле или тэге style , может повлиять на отображение любого элемента DOM-дерева.

Формализация задачи.
Предположим для простоты, что весь JavaScript-код заключен в модули, которые ничего не знают друг о друге и инкапсулируют в себе все необходимое им для своей работы. Модуль знает как сгенерить свое HTML-представление (назовем его блок ) и куда его вставить в DOM-дереве. При этом блоки могут вкладываться друг в друга. На уровне разметки блок состоит из корневого элемента и дочерних элементов .
Задача заключается в том, чтобы на отображение элементов любого блока можно было повлиять только намеренным изменением в HTML-представлении и соответствующих CSS-файлах и тэгах style .

Любое ненамеренное изменение отображения элементов блоков будем называть протечкой стилей .

Протечки стилей могут возникать как при изменениях в свойствах элементов других блоков (протечки свойств ), так и при изменениях в DOM-дереве (каскадные протечки ).

Иточники протечек стилей
Если рассматривать какой-либо блок сам по себе, то протечки стилей могут быть как извне, так и наружу. В связи с тем, что протечка наружу для одного блока будет являться протечкой извне для другого, при классификации протечек можно ограничиться случаем протечек извне.
1. Наследование свойств
При отсутствии у CSS-свойства какого-либо элемента явно заданного значения используется значение по умолчанию. Если это значение inherit , то значение свойства задается равным значению свойства родительского элемента.
Таким образом, корневой элемент текущего блока может наследовать стили своего родителя, по определению принадлежащего другому блоку.

К примеру,
.outer-block{ color: red; }

Я красный из-за наследования стилей

2. Конформизм свойств
При отсутствии у CSS-свойства какого-либо элемента явно заданного значения используется значение по умолчанию. Если это свойство подстраивается под свойство родительского элемента (к примеру, как свойства width и height со значением по умолчанию auto) или мимикрирует (к примеру, как свойство background-color со значением по умолчанию transparent), то у конечного пользователя будет создаваться впечатление, что стили родительского элемента протекли на стили дочернего элемента.

К примеру,
.outer-block{ background: red; }

Я намеренно сделан красным
Я красный из-за конформизма стилей

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

3. Каскадный беспредел
Применение стилей к целевым элементам селекторов происходит в три этапа.
На первом этапе из всего DOM-дерева выбираются все элементы, соответствующие селектору целевого элемента. К примеру, для селектора.current-block h3 на первом этапе будут выбраны все элементы с тэгом h3 . Способа ограничить пространство выбора каким-либо участком DOM-дерева не существует.
На втором этапе выбранные элементы фильтруются на предмет соответствия селектору путем обхода родительских элементов целевого элемента. При использовании комбинатора потомка пробел (descendant combinator) поиск соответствия может идти вплоть до корневого элемента DOM-дерева. При использовании сестринского комбинатора ~ (general sibling combinator) - до самого первого сестринского элемента.

К примеру,
.current-block h3 { background: blue; } .outer-block h3 { background: red; }

Я намеренно сделан красным

Я красный из-за каскадного беспредела


Единственным способом ограничить пространство поиска является использование дочернего комбинатора > (child combinator) и ближайшего сестринского комбинатора + (adjacent sibling combinator). Для этого необходимо задавать точный путь в DOM-дереве от целевого элемента к корневому элементу блока, что приводит к увеличению связанности CSS и HTML-кода.

На третьем этапе выбранным и отфильтрованным целевым элементам назначаются стилевые свойства. При этом, если на один и тот же целевой элемент претендуют несколько селекторов, каждый со своим вариантом свойства, то значение свойства определяется на основе специфичности селекторов, а при ее равенстве - на основе порядка объявления.

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

4. Позиционная обусловленность
Элементы блоков могут менять свое отображение в зависимости от позиции блока в DOM-дереве при использовании в селекторах сестринских комбинаторов (+ и ~) или псевдоклассов (:first-child и т.п.).

К примеру,

Block { background: red; } .block + .block { background: blue; }

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

В процессе этих трансформаций и миграций выяснилось, что рост трудоемкости создания и поддержания веб-интерфейса значительно опережает рост его сложности. Проблему пытались (и пытаются до сих пор) решить путем разбиения на модули, абстрагирования, инкапсуляции. С этой целю было создано большое количество JavaScript-фреймворков (Backbone , Ember , Angular), HTML-шаблонизаторов (Jade , Handlebars), систем управления зависимостями (RequireJS) и т.п.

Наиболее сложным с этой точки зрения оказался CSS, где по дизайну языка любое свойство, объявленное в любом подключенном CSS-файле или тэге style , может повлиять на отображение любого элемента DOM-дерева.

Формализация задачи.
Предположим для простоты, что весь JavaScript-код заключен в модули, которые ничего не знают друг о друге и инкапсулируют в себе все необходимое им для своей работы. Модуль знает как сгенерить свое HTML-представление (назовем его блок ) и куда его вставить в DOM-дереве. При этом блоки могут вкладываться друг в друга. На уровне разметки блок состоит из корневого элемента и дочерних элементов .
Задача заключается в том, чтобы на отображение элементов любого блока можно было повлиять только намеренным изменением в HTML-представлении и соответствующих CSS-файлах и тэгах style .

Любое ненамеренное изменение отображения элементов блоков будем называть протечкой стилей .

Протечки стилей могут возникать как при изменениях в свойствах элементов других блоков (протечки свойств ), так и при изменениях в DOM-дереве (каскадные протечки ).

Иточники протечек стилей
Если рассматривать какой-либо блок сам по себе, то протечки стилей могут быть как извне, так и наружу. В связи с тем, что протечка наружу для одного блока будет являться протечкой извне для другого, при классификации протечек можно ограничиться случаем протечек извне.
1. Наследование свойств
При отсутствии у CSS-свойства какого-либо элемента явно заданного значения используется значение по умолчанию. Если это значение inherit , то значение свойства задается равным значению свойства родительского элемента.
Таким образом, корневой элемент текущего блока может наследовать стили своего родителя, по определению принадлежащего другому блоку.

К примеру,
.outer-block{ color: red; }

Я красный из-за наследования стилей

2. Конформизм свойств
При отсутствии у CSS-свойства какого-либо элемента явно заданного значения используется значение по умолчанию. Если это свойство подстраивается под свойство родительского элемента (к примеру, как свойства width и height со значением по умолчанию auto) или мимикрирует (к примеру, как свойство background-color со значением по умолчанию transparent), то у конечного пользователя будет создаваться впечатление, что стили родительского элемента протекли на стили дочернего элемента.

К примеру,
.outer-block{ background: red; }

Я намеренно сделан красным
Я красный из-за конформизма стилей

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

3. Каскадный беспредел
Применение стилей к целевым элементам селекторов происходит в три этапа.
На первом этапе из всего DOM-дерева выбираются все элементы, соответствующие селектору целевого элемента. К примеру, для селектора.current-block h3 на первом этапе будут выбраны все элементы с тэгом h3 . Способа ограничить пространство выбора каким-либо участком DOM-дерева не существует.
На втором этапе выбранные элементы фильтруются на предмет соответствия селектору путем обхода родительских элементов целевого элемента. При использовании комбинатора потомка пробел (descendant combinator) поиск соответствия может идти вплоть до корневого элемента DOM-дерева. При использовании сестринского комбинатора ~ (general sibling combinator) - до самого первого сестринского элемента.

К примеру,
.current-block h3 { background: blue; } .outer-block h3 { background: red; }

Я намеренно сделан красным

Я красный из-за каскадного беспредела


Единственным способом ограничить пространство поиска является использование дочернего комбинатора > (child combinator) и ближайшего сестринского комбинатора + (adjacent sibling combinator). Для этого необходимо задавать точный путь в DOM-дереве от целевого элемента к корневому элементу блока, что приводит к увеличению связанности CSS и HTML-кода.

На третьем этапе выбранным и отфильтрованным целевым элементам назначаются стилевые свойства. При этом, если на один и тот же целевой элемент претендуют несколько селекторов, каждый со своим вариантом свойства, то значение свойства определяется на основе специфичности селекторов, а при ее равенстве - на основе порядка объявления.

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

4. Позиционная обусловленность
Элементы блоков могут менять свое отображение в зависимости от позиции блока в DOM-дереве при использовании в селекторах сестринских комбинаторов (+ и ~) или псевдоклассов (:first-child и т.п.).

К примеру,

Block { background: red; } .block + .block { background: blue; }

Наследование CSS-свойств

Большинство свойств не передают дочернему элементу свои значения от родителя

У некоторых значение по умолчанию подстраивается под родителя

И лишь немногие (см. список свойств CSS2, если в графе «Inherited» указано «yes») наследуют значение свойства от родителя

Свойство, меняющее все стили CSS, кроме direction и unicode-bidi

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

CSS наследование стилей от родителя: inherit

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

inherit передаёт не конечное значение, а то, что указано в стилях родителя

Пример 1: в чём разница между width: inherit; и width: 100%;

Пример 2: max-height: 100%; не работает

Пример 3: как сделать дубликат стилей CSS родителя

inherit переносит значение непосредственного родителя, а не определённого position

Копируется всё, даже то, что не указано разработчиком в стилях у родителя

initial CSS: отменить наследование

Для того, чтобы узнать начальные значения свойств, которые зависят от браузера, таких как color и font-family , можно применить initial

Пример 1: запретить наследование свойства

Пример 2: убрать свойство для более узкого селектора

initial позволяет сбросить все стили, включая те, что браузер задал для тега по умолчанию

Пример: для сторонних виджетов отключить наследование стиля и стили, установленные браузером

unset CSS: сбросить стиль браузера

Поведение стандартное, только все теги становятся обезличенными, словно их подстригли под одну гребёнку. То есть как и у initial , блочные элементы станут inline .

Пример: обнулить все возможные стили input

Домашнее задание: в комментариях предложить свой пример использования значений inherit, initial и unset, а то у меня фантазия уже исчерпана 🙂

5 комментариев:

Анонимный Здравствуйте!
Не подскажите почему так?
https://jsfiddle.net/og96q6x5/

Почему этот негодяй Н2 сдвигает жёлтый ДИВ в низ. Я вообще хотел без красного. Он жёлтый сдвинул. Я его ещё в один ДИВ так он сдвинул и жёлтый и красный.
Почему?
NMitra Здравствуйте, насколько я поняла вас не устраивает схлопывание? Посмотрите http://shpargalkablog.ru/2011/03/svoistva-margin-padding.html#m-parent Там есть решения проблемы Анонимный Спасибо Вам. Эту пробелку я уже нарыл как решать это схлопывание. Или как у Вас или чистящим ДИВом.

Не у меня другое.
Вот получилось. Что и хотел.
Вроде получилось его усмирить с display:inline-block.
https://jsfiddle.net/og96q6x5/2/

Но вопрос остался. Разве находясь внутри ДИВа он не должен двигаться по этому диву. Никого не трогать?
И почему при display:inline margiņ-top: Не работает?
https://jsfiddle.net/og96q6x5/1/
Анонимный Спасибо Нашёл.
vertical-align: с display:inline; и display:inline-block;

Даа. Как всё это забавно.
NMitra И почему при display:inline margiņ-top не работает? — Потому что он не блочный, у него нет высоты height

shpargalkablog.ru

Может ли класс CSS наследовать один или несколько других классов?

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

Мой вопрос в том, можно ли сделать класс CSS, который «наследует» от другого класса CSS (или более одного).

Например, скажем, что у нас было:

Что бы я хотел сделать, это примерно так:

где класс.composite будет отображаться в строке и иметь красный фон

27 ответов

Есть такие инструменты, как LESS, которые позволяют вам составлять CSS на более высоком уровне абстракции, аналогичном тому, что вы описываете.

Меньше вызовов этих «миксинов»

Вы можете добавить несколько классов в один элемент DOM, например.

Наследование не входит в стандарт CSS.

Да, но не совсем с этим синтаксисом.

Элемент может принимать несколько классов:

И это примерно так же близко, как вы к сожалению. Мне бы очень хотелось увидеть эту функцию вместе с классными алиасами.

Сохраняйте общие атрибуты и назначайте определенные (или переопределяющие) атрибуты снова.

Нет, вы не можете сделать что-то вроде

Это не «имена классов» в смысле OO. .something и.else больше не являются селекторами.

Но вы можете указать два класса для элемента

или вы можете изучить другую форму наследования

Если абстракции backgroundcolor и color наследуются от настроек в охватывающем div, который имеет стиль.foo . Возможно, вам придется проверить точную спецификацию W3C. inherit по умолчанию для большинства свойств по умолчанию, но не для всех.

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

Это найдет все элементы с классом «композит» и добавит к элементам классы «что-то» и «еще». Итак, что-то вроде

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

Так как super выглядит так же, как footer , но с другим шрифтом, я буду использовать метод включения Less class (они называют его mixin), чтобы он также включил эти объявления:

Лучшее, что вы можете сделать, это

SCSS для данного примера будет выглядеть примерно так:

К сожалению, CSS не обеспечивает «наследование» так, как это делают языки программирования, такие как С++, С# или Java. Вы не можете объявить класс CSS, а затем расширить его с помощью другого класса CSS.

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

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

Как правило, стили объединяются, но когда возникают конфликты, более поздний объявленный стиль обычно выигрывает (если только важный атрибут не указан в одном из стилей, и в этом случае выигрывает). Кроме того, стили, применяемые непосредственно к элементу HTML, имеют приоритет над стилями класса CSS.

Я понимаю, что этот вопрос сейчас очень старый, но здесь нет ничего!

Если цель состоит в том, чтобы добавить один класс, который подразумевает свойства нескольких классов, как собственное решение, я бы рекомендовал использовать JavaScript/jQuery (jQuery действительно не нужен, но, безусловно, полезен)

Если у вас есть, например, .umbrellaClass , который «наследует» от.baseClass1 и.baseClass2 , у вас может быть какой-то JavaScript, готовый к работе.

Теперь все элементы.umbrellaClass будут иметь все свойства как.baseClass s. Обратите внимание, что, подобно наследованию ООП, .umbrellaClass может иметь или не иметь свои собственные свойства.

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

Отстой css не имеет нативного наследования.

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

Наследованием называется перенос правил форматирования для элементов, находящихся внутри других. Такие элементы являются дочерними, и они наследуют некоторые стилевые свойства своих родителей, внутри которых располагаются.

Разберём наследование на примере таблицы. Особенностью таблиц можно считать строгую иерархическую структуру тегов. Вначале следует контейнер

Пример 18.1. Наследование параметров цвета

HTML5 CSS 2.1 IE Cr Op Sa Fx

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

Чтобы определить, наследуется значение стилевого свойства или нет, требуется заглянуть в справочник по свойствам CSS и посмотреть там. Подключать свою интуицию в подобном случае бесполезно, может и подвести.

Наследование позволяет задавать значения некоторых свойств единожды, определяя их для родителей верхнего уровня. Допустим, требуется установить цвет и шрифт для основного текста. Достаточно воспользоваться селектором BODY , добавить для него желаемые свойства, и цвет текста внутри абзацев и других текстовых элементов поменяется автоматически (пример 18.2).

Пример 18.2. Параметры текста для всей веб-страницы

В данном примере рубленый шрифт и цвет текста абзацев устанавливается с помощью селектора BODY . Благодаря наследованию уже нет нужды задавать цвет для каждого элемента документа в отдельности. Однако бывают варианты, когда требуется всё-таки изменить цвет для отдельного контейнера. В этом случае придётся переопределять нужные параметры явно, как показано в примере 18.3.

Пример 18.3. Изменение свойств наследуемого элемента

В данном примере цвет первого абзаца наследуется от селектора BODY , а для второго установлен явно через класс с именем red .

Наследование свойств css

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

В процессе этих трансформаций и миграций выяснилось, что рост трудоемкости создания и поддержания веб-интерфейса значительно опережает рост его сложности. Проблему пытались (и пытаются до сих пор) решить путем разбиения на модули, абстрагирования, инкапсуляции. С этой целю было создано большое количество JavaScript-фреймворков (Backbone , Ember , Angular), HTML-шаблонизаторов (Jade , Handlebars), систем управления зависимостями (RequireJS) и т.п.

Наиболее сложным с этой точки зрения оказался CSS, где по дизайну языка любое свойство, объявленное в любом подключенном CSS-файле или тэге style , может повлиять на отображение любого элемента DOM-дерева.

Формализация задачи.

Предположим для простоты, что весь JavaScript-код заключен в модули, которые ничего не знают друг о друге и инкапсулируют в себе все необходимое им для своей работы. Модуль знает как сгенерить свое HTML-представление (назовем его блок ) и куда его вставить в DOM-дереве. При этом блоки могут вкладываться друг в друга. На уровне разметки блок состоит из корневого элемента и дочерних элементов .
Задача заключается в том, чтобы на отображение элементов любого блока можно было повлиять только намеренным изменением в HTML-представлении и соответствующих CSS-файлах и тэгах style .

Любое ненамеренное изменение отображения элементов блоков будем называть протечкой стилей .

Протечки стилей могут возникать как при изменениях в свойствах элементов других блоков (протечки свойств ), так и при изменениях в DOM-дереве (каскадные протечки ).

Иточники протечек стилей

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

1. Наследование свойств

При отсутствии у CSS-свойства какого-либо элемента явно заданного значения используется значение по умолчанию. Если это значение inherit , то значение свойства задается равным значению свойства родительского элемента.
Таким образом, корневой элемент текущего блока может наследовать стили своего родителя, по определению принадлежащего другому блоку.

2. Конформизм свойств

При отсутствии у CSS-свойства какого-либо элемента явно заданного значения используется значение по умолчанию. Если это свойство подстраивается под свойство родительского элемента (к примеру, как свойства width и height со значением по умолчанию auto) или мимикрирует (к примеру, как свойство background-color со значением по умолчанию transparent), то у конечного пользователя будет создаваться впечатление, что стили родительского элемента протекли на стили дочернего элемента.

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

3. Каскадный беспредел

(general sibling combinator) - до самого первого сестринского элемента.

Единственным способом ограничить пространство поиска является использование дочернего комбинатора > (child combinator) и ближайшего сестринского комбинатора + (adjacent sibling combinator). Для этого необходимо задавать точный путь в DOM-дереве от целевого элемента к корневому элементу блока, что приводит к увеличению связанности CSS и HTML-кода.

На третьем этапе выбранным и отфильтрованным целевым элементам назначаются стилевые свойства. При этом, если на один и тот же целевой элемент претендуют несколько селекторов, каждый со своим вариантом свойства, то значение свойства определяется на основе специфичности селекторов, а при ее равенстве - на основе порядка объявления.

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

4. Позиционная обусловленность

) или псевдоклассов (:first-child и т.п.).

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

Очевидно, что идеальная инкапсуляция CSS-стилей должна устранять любые возможности для их протечек.

Вторая часть статьи («Инкапсуляция CSS-стилей - Часть 2. Решения») будет посвящена анализу того, насколько текущие подходы (OOCSS, SMACSS, ACSS, BEM, CSS-препроцессоры) соответствуют идеалу, а также их классификации.

Буду рад полезным советам и конструктивной критике.

Наследование и группирование в CSS

Здравствуйте, уважаемые читатели! Сегодня в рамках рубрики «Учебник CSS» важнейшие понятия группирования и наследования в CSS . Кто уже давно следит за моими публикациями, наверное, уже проникся мыслью о необходимости постижения основ каскадных таблиц стилей (Cascading Style Sheets). И это правильно, поскольку современный вебмастер непременно должен знать базовые понятия и алгоритм применения основных знаний HTML и CSS на практике.

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

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

Группирование в CSS

Возьмем для примера теги заголовков h1 h2 h3, стили которых прописаны в файле style.css. Например, так:

Если вы внимательно посмотрите, то можете заметить, что для тегов всех заголовков есть одна общая составляющая стилей CSS, а именно значение font-family, которое определяет вид шрифта. Можно объединить селекторы h1-h3 по этому признаку и составить для них общее правило касательно значения font-family:

А индивидуальные свойства для каждого селектора, которые не являются общими, оформить отдельно:

Это и есть группирование в CSS. Оно позволяет несколько оптимизировать записи оформления стилей и дает возможность упростить чтение документа. Думаю, с этим мы разобрались, ничего сложного здесь нет, переходим к понятию наследования .

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

Как совершенно явно вытекает из самого названия, наследование предполагает перенос правил стилей для элементов, находящихся внутри других. Такие элементы называются дочерними и они наследуют стилевые свойства своих родителей. Наиболее удачным примером, на котором можно наглядно исследовать нюансы наследования CSS, является, на мой скромный взгляд, таблица html, которая создается с помощью тегов table, tr и td. Допустим, заданы свойства оформления для тега table:

Теперь составим простенькую таблицу из 4 ячеек:

На вебстранице она будет выглядеть следующим образом:

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

Например, border определяет рамку вокруг таблицы, но не вокруг ячеек, поэтому эти ячейки не выделены рамкой внутри таблицы. Также не наследуется свойство background. Однако, в этом случае возникает вопрос: почему же цвет фона ячеек приобрел песочный цвет, который указан в качестве значения родительского тега table, если он не наследуется?

Здесь все дело в том, что у свойства background в качестве значения по умолчанию для тега td выступает transparent, то есть прозрачность . Таким образом, цвет фона родительского элемента “просматривается” сквозь фон дочернего элемента, который является прозрачным. Отмечу, что во многих случаях для большинства свойств CSS предусмотрены значения по умолчанию. Поэтому, если для какого-то свойства явно не заданы параметры, до вступает в силу предусмотренное значение по умолчанию.

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

Теперь любой абзац на данной вебстранице, например, такой:

Будет оформлен соответствующим стилем:

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

Теперь обычный параграф на странице будет иметь такой вид:

А уникальный параграф с отдельно прописанным значением color будет таким:

Вот так, используя там, где это необходимо, алгоритмы группирования и наследования, можно максимально оптимизировать файл стилей, сделав его одновременно легко читаемым. Я уже упоминал выше что не все свойства CSS наследуются, поэтому приведу вам одну из страниц официального сайта W3C, где вы при желании можете почерпнуть более подробную информацию по этому вопросу. Итак, страница «Full property table»:

На скриншоте красной рамкой обведены данные о том, какие свойства CSS наследуются, а какие — нет. И напоследок разъясню более подробно по столбцам, какая информация здесь представлена:

«Name» — название CSS свойства;
«Values» — все возможные значения для этого свойства;
«Initial value» — начальное значение для данного свойства, которое используется по умолчанию (об этом я упоминал)
«Applies to» — к каким элементам применяется правило, в которое входит свойство CSS;
«Inherited?» — наследуется это правило или нет.

Это все, о чем я хотел сегодня вам рассказать. Постарался преподать нюансы группирования и наследования CSS максимально доступно и эффективно. Как это у меня получилось? Судить вам. Уровень вашей активности при подписке на новые материалы блога дадут ответ на этот вопрос. Засим разрешите откланяться. Напоследок не помешает небольшая разрядка, особенно тем, кто неравнодушен к КВН:


goldbusinessnet.com

Порог вхождения в 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 каждому атрибуту (например ), классу или псевдоклассу (:link или:hover); добавить 100 для каждого ID, а к inline стилю добавить 1000. Давайте подсчитаем специфичность следующих селекторов, используя данный метод: p.note - 1 класс + 1 элемент = 11 #sidebar p - 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()
  • 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. Особенно в случае специфичности важно знать, как она влияет на таблицы стилей и как планировать её так, чтобы она вызывала лишь минимальное количество проблем при кодировании. А лучше, чтобы вообще не вызывала.