Программирование на Python и Objective-C в Mac OS

Программирование на Python и Objective-C под Mac OS и для iPhone / iPod Touch

Что в css означает: Что в CSS означает знак «>»? — Хабр Q&A

Содержание

Что такое селекторы CSS.

HTML-страницы, к которым могут применяться стили CSS, могут содержать огромное количество элементов.

Это могут быть:

+ Текст (вполоть для каждой буквы, каждого абзаца и.т.д.)

+  Изображения

+ Таблицы (каждая их строка, столбец или ячейка, и.т.д.)

+ Списки

+ и.т.д.

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

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

В технологии CSS это можно сделать с помощью так называемых селекторов.

Селекторы ( от англ. select — выбирать) — это элементы каскадной таблицы стилей CSS, которые указывают на тот элемент на веб-странице, к которому должны будут применяться стили.

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

В CSS селекторы располагаются самой первой составляющей стиля.

Синтаксис здесь следующий:

селектор {
стили, которые будут применяться к элементу выбранному этим селектором
}

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

По-сути, весь CSS-файл и состоит из таких конструкций, указания селекторов и стилей, которые к ним относятся.

селектор1 {
   стили
}

селектор2 {
   стили
}

селектор3 {
   стили
}
и.т.д.

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

Изучаем селекторы в CSS

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

В этой статье мы рассмотрим способы определения стилей веб-страницы с помощью селекторов классов, селекторов потомков, псевдоклассов и селекторов идентификаторов.

Для примера нам нужен только один HTML-файл и таблица стилей CSS. Создайте папку css-selectors и веб-страницу под названием selectors.html со следующей разметкой:

<!DOCTYPE html>
<html lang='en'>
  <head>
    <meta charset='UTF-8'/>
    <title>Селекторы CSS</title>
    <link rel='stylesheet' href='styles.css'/>
  </head>
  <body>
    <h2> Селекторы CSS</h2>
    <p>Селекторы CSS позволяют <em>выбрать</em> отдельный HTML-элемент в документе HTML.
       Это <strong>супер</strong> полезно.</p>
    <p>Классы чрезвычайно важны, так как они позволяют выбрать
       произвольные блоки на странице.</p>
    <p>Мы так же рассмотрим в этом примере ссылки, поэтому вот ссылка
       <a href='https://internetingishard.com'>Interneting Is Hard</a>, для которой нам нужно задать стили.</p>
    <div>Кнопка Один</div>
  </body>
</html>

Теперь создадим в той же папке файл styles.css. Это все, что понадобится для изучения CSS селекторов.

Селекторы классов позволяют применять стили CSS к определенному элементу HTML. Они дают возможность различать элементы HTML одного и того же типа. Например, когда есть два элемента <div>, но необходимо задать стили только для одного из них. Для селекторов классов нужны:

  • Указанный атрибут класса в элементе HTML;
  • Соответствующий селектор классов CSS.

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

<p> Селекторы CSS позволяют <em>выбрать</em> отдельный HTML-элемент в документе HTML. Это <strong>супер</strong> полезно.</p>

Теперь стилизуем абзац <p class=’synopsis’> в файле CSS с помощью следующего кода:

.synopsis {
  color: #7E8184;        /* Светло серый */
  font-style: italic;
}

Это правило применяется только к элементам с соответствующим атрибутом класса. Обратите внимание на точку (.) — префикс перед именем класса. Это отличает соседние селекторы CSS классов от селекторов типов:

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

Добавление атрибута class не изменяет смысловое значение HTML-документа и служит для подключения CSS. Рекомендуется избегать имен классов, основанных на том, как они отображаются. Использование чего-то более семантического, например, .synopsis, дает больше свободы в действиях. Что позволяет настроить отображение этого абзаца.

Атрибут class применяется не только к элементам <p> — он может быть использован для любого элемента HTML. Взяв на вооружение селекторы классов CSS, можно сделать блоки <div> и <span> намного более полезными. Мы можем использовать их для создания, как отдельных элементов, так и произвольных разделов веб-страницы:

Начнем с отдельных элементов. На этот раз мы будем использовать класс вместо CSS селектора div. Добавьте следующий код в файл styles.css:

.button {
  color: #FFF;
  background-color: #5995DA;    /* Синий */
  font-weight: bold;
  padding: 20px;
  text-align: center;
  border: 2px solid #5D6063;    /* Темно-серый */
  border-radius: 5px;
  width: 200px;
  margin: 20px auto;
}

Конечно, для этого нам нужен соответствующий атрибут класса. Измените <div> в файле selectors.html на следующий код:

<div>Кнопка Один</div>

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

Помните, что <div> не изменяет семантическую структуру страницы. Это делает его отличным инструментом для определения представляемой структуры веб-страницы. Обертывая HTML-элементы в теги <div>, можно создать сайт с помощью более крупных фрагментов, не влияя на то, как поисковые системы просматривают наш контент:

Попробуем создать макет фиксированной ширины с использованием метода автополей. Сначала оберните весь документ в <div> и присвойте ему уникальный класс:

<body>
<div>  <!-- Добавьте это -->
<h2> Селекторы CSS</h2>
    <p >Селекторы CSS позволяют <em>выбрать</em> отдельный HTML-элемент в документе HTML.
       Это <strong>супер</strong> полезно.</p>
    <p>Классы чрезвычайно важны,, так как они позволяют выбрать
       произвольные блоки на странице.</p>
    <p>Мы так же рассмотрим в этом примере ссылки, поэтому вот ссылка
       <a href='https://internetingishard.com'>Interneting Is Hard</a>, для которой нам нужно задать стили.</p>
    <div>Кнопка Один</div>
</div>  <!-- Добавьте это -->
</body>
Затем добавьте следующий код в файл styles.css:
.page {
  width: 600px;
  margin: 0 auto;
}

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

Именно таким образом определяются более сложные макеты веб-страниц. Например, если на нашей странице была бы боковая панель, мы бы вложили все ее элементы в другой <div> с классом .sidebar.

Без CSS селекторов атрибутов классов, которые позволяют дифференцировать элементы <div>, ничего из этого не было бы возможно.

Один и тот же класс может применяться к нескольким элементам в рамках одного HTML-документа. Это означает, что можно использовать произвольные объявления CSS везде. Чтобы создать еще одну кнопку, нужно добавить еще один HTML-элемент с тем же классом:

<div>Кнопка Один</div>
<div>Кнопка Два</div>

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

Что, если мы захотим немного изменить вторую кнопку? К счастью, можно применить несколько классов к одному и тому же HTML-элементу. Стили из каждого класса будут применены к элементу, что даст возможность повторно использовать стили .button и одновременно переопределить некоторые из них новым классом:

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

<div>Кнопка Два</div>

Этому элементу теперь присвоено два разных класса, и можно использовать любой из них для определения стилей. Это дает некоторые дополнительные возможности. Можно задать для второй кнопки стили класса .button и стили, относящиеся только к этой кнопке класса .call-to-action (обязательно добавьте этот код после правила .button):

.call-to-action {
  font-style: italic;
  background-color: #EEB75A;    /* Желтый */
}

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

  • Это добавление нового объявления по сравнению с исходным правилом .button — font-style;
  • Переопределение существующего в классе .button стиля — background-color.

Переопределение дочерних селекторов в CSS происходит из-за порядка размещения правил .call-to-action и .button в таблице стилей. Когда в файле CSS есть два противоречащих друг другу свойства, всегда применяется то, которое указано последним. Если бы вы разместили .call-to-action перед .button, применялось бы это правило, и кнопка осталась бы синей.

Это означает, что порядок атрибутов класса в HTML-элементе не влияет на поведение переопределения. Несколько классов в одном элементе применяются «одинаково», а приоритет определяется исключительно порядком размещения правил в файле styles.css.

Другими словами, следующие элементы эквивалентны:

<!-- В результате элементы будут отображаться на странице одинаково -->
<div>Кнопка Два</div>
<div>Кнопка Два</div>

Возможно, вы заметили, что <em> в нашем первом абзаце больше нельзя отличить от остального текста абзаца, так как правило .synopsis задает отображение курсивом всего текста абзаца.

Чтобы изменить этот элемент <em>, можно было бы добавить к нему еще один класс. Но это приведет к тому, что код будет не очень удобен. Мы хотим иметь правило .synopsis в качестве отдельного независимого компонента, для которого можно полностью задать стили через CSS. То есть без необходимости внесения изменений в HTML только для того, чтобы изменить какие-то стили:

Это то, для чего предназначены CSS селекторы потомков. Они позволяют настраивать только те элементы, которые находятся внутри другого элемента. Например, можно вывести этот элемент <em> в абзаце .synopsis со следующими стилями:

.synopsis em {
  font-style: normal;
}

Добавление этого правила в файл styles.css задаст отображение <em> вертикальными (римскими) символами, тем самым определяя разницу с курсивным шрифтом, которым отображается весь абзац <p>. При этом остальных элементов <em>, размещенных на странице это изменение не коснется:

Селекторы потомков не ограничиваются селекторами классов. Таким образом, можно комбинировать любую другую группу селекторов. Например, если нужно выбрать только элементы <em> внутри заголовков:

h2 em {
  /* определенные стили */
}

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

/* Старайтесь избегать такого */
.article h3 .subheading em {
  /* Конкретные стили */
}

Эти стили нельзя будет повторно использовать, поскольку они соответствуют только следующей структуре HTML:

<div>
  <h3>
    <span>Это <em>на самом деле</em> особенный текст.</span>
  </h3>
</div>

Если захотите применить эти стили к заголовку <h3>, который не был обернут в тег <div class = ‘article’>, придется здорово поломать голову. Та же ситуация, если вы захотите применить их к заголовку <h4>.

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

Классический пример — это ссылка. Веб-разработчик создает элемент <a href>. После того как браузер отобразил его, пользователи могут взаимодействовать с этой ссылкой: навести на нее курсор мыши, кликнуть ссылку и перейти по ней:

Псевдоклассы CSS предоставляют механизм для подключения к таким действиям пользователя. В любой момент времени элемент <a href> может находиться в нескольких состояниях, и можно использовать псевдоклассы для определения отдельных стилей для каждого из этих состояний. Можно представить их как селекторы классов, которые не нужно писать самостоятельно, потому что они встроены в браузер.

В отличие от CSS селекторов псевдоклассы начинаются с двоеточия, за которым следует имя класса. Наиболее распространенными псевдоклассами ссылок являются:

  • :link — ссылка, по которой пользователь еще не переходил;
  • :visited — ссылка, по которой пользователь переходил раньше;
  • :hover — ссылка, на которую пользователь навел курсор мыши;
  • :active — ссылка, нажатая мышью (или пальцем).

Рассмотрим эти псевдоклассы, добавив следующие правила в CSS (также обратите внимание на то, что мы используем для обозначения цветов ключевые слова, а не шестнадцатеричные коды):

a:link {
  color: blue;
  text-decoration: none;
}
a:visited {
  color: purple;
}
a:hover {
  color: aqua;
  text-decoration: underline;
}
a:active {
  color: red;
}

Приведенный выше фрагмент кода отлично подходит для большинства сайтов, но давайте более внимательно рассмотрим поведение a:visited, когда мы изменим атрибут href на URL-адрес, который раньше посещали. Стиль a:hover применяется как к ранее посещенным ссылкам, так и к тем, по которым мы еще не переходили. Можно еще больше модифицировать ссылки, объединив псевдоклассы.

Добавьте это правило ниже предыдущего фрагмента кода:

a:visited:hover {
  color: orange;
}

Данный код создает специальный стиль для состояния при наведении курсора мыши на посещенные ранее ссылки. Наведя курсор на не посещенную ранее ссылку, мы увидим, что она «перекрашивается» в аквамариновый цвет. А при наведении курсора на посещенную ссылку она становится оранжевой. Фантастика! Но это ломает наш стиль a:active из-за некоторых внутренних аспектов CSS, о которых вы никогда не захотите читать. Когда вы нажмете на ссылку, она больше не будет становиться красной.

Можно исправить это с помощью CSS псевдоселектора a:visited:active. Добавьте следующий код в конец таблицы стилей. Обратите внимание, что, как и в случае с классом .call-to-action, порядок, в котором правила определяются в файле styles.css, имеет значение:

a:visited:active {
  color: red;
}

Эти два последних раздела позволят задавать стили посещенных ссылок полностью отдельно от не посещенных.

Псевдоклассы предназначены не только для определения стилей ссылок. Вместо указания стилей для класса a:link и потомков изменим с помощью псевдоклассов класс .button. Это позволит создавать кнопки, которые ведут куда-то.

Сначала нужно изменить кнопки, чтобы они стали элементами <a href>, а не просто элементами <div>, как показано ниже:

<a href='nowhere.html'>Кнопка Один</a>
<a href='nowhere.html'>Кнопка Два</a>

Если вы перезагрузите документ в браузере, то увидите, что некоторые стили больше не действуют. Хотя мы используем одни и те же классы. Это связано с тем, что <a> является встроенным элементом, а также имеет значение цвета по умолчанию:

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

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

.button:link,                 /* Измените это */
.button:visited {             /* Измените это */
  display: block;             /* Добавьте это */
  text-decoration: none;      /* Добавьте это */
  color: #FFF;                /* Все остальное остается без изменений */
  background-color: #5995DA;
  font-weight: bold;
  padding: 20px;
  text-align: center;
  border: 2px solid #5D6063;
  border-radius: 5px;
  width: 200px;
  margin: 20px auto;
}

Обратите внимание на новые псевдоклассы :link и :visited в селекторе. Без них стиль браузера по умолчанию для a:link не изменился бы. Теперь оформим состояние при наведении курсора.

.button:hover,
.button:visited:hover {
  color: #FFF;
  background-color: #76AEED;  /* Light blue */
}

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

.button:active,
.button:visited:active {
  color: #FFF;
  background-color: #5995DA;  /* Blue */
}

Стили, которые мы только что определили, готовы к повторному использованию. Назначьте класс .button любому HTML-элементу, и вы превратите его в интерактивную кнопку.

Займемся второй кнопкой. Предполагается, что она имеет желтый фон, но мы изменили это кодом из предыдущего раздела. Наш селектор .button:link более «специфичен», чем текущее правило .call-to-action, поэтому он имеет приоритет.

Исправим такое положение вещей, применив к нашему правилу .call-to-action несколько псевдоклассов. Замените существующее правило следующим (убедитесь, что это определено после новых стилей .button из предыдущего раздела о дочерних селекторах в CSS):

.call-to-action:link,
.call-to-action:visited {
  font-style: italic;
  background-color: #EEB75A;     /* Желтый */
}
.call-to-action:hover,
.call-to-action:visited:hover {
  background-color: #F5CF8E;     /* Светло-желтый */
}
.call-to-action:active,
.call-to-action:visited:active {
  background-color: #EEB75A;     /* Желтый */
}

Мы назначили класс .call-to-action только для второй кнопки, поэтому только она станет желтой. Конечно, нам по-прежнему нужно, чтобы класс .button был назначен для обоих элементов <a>, поскольку он определяет общие стили, такие как отступы, радиус границы и размер шрифта.

Состояния ссылок – это лишь один аспект псевдоклассов. Существует также множество других псевдоклассов, которые предоставляют дополнительную информацию о контексте элемента. Например, псевдокласс last-of-type выбирает последний элемент определенного типа в родительском элементе. Это является альтернативой селекторам классов.

Например, мы могли бы использовать :last-of-type, чтобы добавить в наш пример определенное пространство после последнего абзаца страницы:

p:last-of-type {
  margin-bottom: 50px;
}

Это позволяет не затрагивать первые два элемента <p> на странице, не добавляя для последнего абзаца новый атрибут класса:

Можно даже использовать псевдокласс :first-of-type вместо класса .synopsis. Заменив существующее правило .synopsis следующим фрагментом кода, мы получим тот же результат:

p:first-of-type {
  color: #7E8184;
  font-style: italic;
}

Использование этого метода вместо устаревших классов имеет свои преимущества и недостатки. Например, это работает только в том случае, если наш синопсис является элементом <p>. Если бы мы захотели создать синтаксис с несколькими параграфами, объединив много элементов <p> в <div class=’synopsis’>, нам пришлось бы переписать наш CSS-код. С другой стороны, псевдоклассы позволяют задавать стили для определенных элементов, не изменяя HTML. Это дает нам четкое разделение контента от представления.

Но псевдоклассы немного сложнее. Контекстные селекторы CSS first-of-type и last-of-type действуют только внутри своего родительского элемента. Другими словами, p:first-of-type выбирает первый элемент <p> в каждом элементе контейнера.

У нас есть один общий <div>, который обертывает контент (.page), поэтому для нас это не проблема. Но что произойдет, если мы добавим следующий код в нижнюю часть элемента .page:

<div>
  <p>If this page had a sidebar...</p>
  <p>We’d have some problems with pseudo-classes.</p>
</div>

Это иллюстрирует сложность применения псевдоклассов для структуры. Первый элемент <p> здесь также будет соответствовать p:first-of-type, потому что область применения псевдокласса ограничена родительским элементом.

Если вы не хотите затрагивать абзацы в боковой панели, и выбрать только первый <p> в контейнере <div class=’page’>, то нужно ограничить область его применения с помощью селектора дочерних элементов. Например:

.page > p:first-of-type {
  color: #7E8184;
  font-style: italic;
}

Различные разработчики придерживаются разных «школ». Некоторым нравится семантическая природа псевдоклассов, в то время как другие доводят до крайности применение различных подробных атрибутов класса для каждого HTML-элемента.

CSS селекторы идентификаторов – альтернатива селекторам классов. Они работают почти так же, но на странице может размещаться только один элемент с определенным идентификатором. Это означает, что вы не сможете повторно использовать стили.

Вместо атрибута class для любого элемента HTML, используется атрибут id. Попробуйте добавить идентификатор ко второй кнопке:

<a href='nowhere.html'>Кнопка Два</a>

Соответствующий селектор CSS должен начинаться с символа хэша (#). Добавление следующего кода в файл styles.css изменит цвет текста желтой кнопки:

#button-2 {
  color: #5D6063;  /* Dark gray */
}

Проблема в том, что если мы захотим задать этот стиль и для другой кнопки, то нужно присвоить ей еще один уникальный атрибут id. Довольно скоро наш CSS начнет выглядеть довольно «грязно»:

/* (Это тяжело поддерживать) */
#button-2,
#button-3,
#checkout-button,
#menu-bar-call-to-action {
  color: #5D6063;
}

По этой причине использовать CSS селекторы идентификаторов обычно не рекомендуется. Вместо этого используйте селекторы классов.

Атрибуты id должны быть уникальными, поскольку на них указывают «фрагменты URL-адресов». Фрагменты — это элементы, с помощью которых можно указать пользователям на определенную часть веб-страницы. Они выглядят как селекторы идентификаторов, расположенные в конце URL-адреса:

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

<!-- С той же страницы -->
<a href='#button-2'>Go to Button Two</a>
<!-- С другой страницы -->
<a href='selectors.html#button-2'>Go to Button Two</a>

Если вы добавите первый вариант ссылки в разметку страницы selectors.html и кликните по ней, то увидите, что данный URL-адрес значится в адресной строке браузера. Чтобы увидеть, как осуществляется переход ко второй кнопке, нужно добавить на страницу немного произвольного контента или сделать высоту окна маленькой:

Этот пересекающийся функционал является веской причиной для того, чтобы избегать использования идентификаторов. Они создают зависимость между URL-адресами сайта и стилями CSS. Представьте, что вы используете в заголовках кучу атрибутов id в качестве как фрагментов URL-адресов, так и идентификаторов. Если вы забудете обновить таблицу стилей, когда отредактируете URL-адрес, то сломаете свой сайт.

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

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

Если вы добавите следующий код после существующих правил .call-to-action, он переопределит заданный ранее цвет фона. Если вы разместите его в верхней части файла, он сам будет переопределен, и наша кнопка не станет красной. Это ожидаемое поведение:

.call-to-action:link,
.call-to-action:visited {
  background-color: #D55C5F;    /* Красный */
}

Теперь посмотрите, что происходит, когда мы пытаемся сделать то же самое с помощью селектора идентификатора. Во-первых, обязательно удалите предыдущий фрагмент кода, а затем попробуйте добавить приведенный ниже код до существующих правил .call-to-action:

#button-2 {
  background-color: #D55C5F;    /* Красный */
}

CSS селекторы идентификаторов имеют более высокую специфичность, чем селекторы классов, поэтому вторая кнопка будет красной, даже если мы зададим фоновый цвет с помощью .call-to-action:link ниже. Концепция «порядок имеет значение» работает только тогда, когда все правила имеют одинаковую специфичность:

Специфичность селекторов, которые мы рассматривали в этой статье, показана ниже: от максимальной до минимальной:

•	#button-2
•	.button:link и .synopsis em (они равнозначны)
•	.button
•	a:link
•	a

Иногда это приводит к путанице. Это настолько серьезная проблема, что была разработана целая методология под названием «BEM». Суть BEM заключается в попытке обеспечить то, чтобы правила CSS были многоразовыми, сделав все селекторами классов. Это исключает возможность возникновения проблем.

В этой статье вы получили практический опыт работы с CSS селекторами классов, селекторами потомков, псевдоклассами, стилями ссылок и селекторами идентификаторов. Цель всех, описанных в этой статье приемов – обеспечить возможность указать определенный HTML-элемент из CSS-кода. Селекторы классов являются самыми универсальными и имеют наименьшее количество недостатков.

Пожалуйста, оставьте свои комментарии по текущей теме материала. Мы очень благодарим вас за ваши комментарии, подписки, отклики, лайки, дизлайки!

Данная публикация является переводом статьи «css selectors» , подготовленная редакцией проекта.

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

Когда вы устанавливаете некоторые свойства селектора в CSS, они наследуются всеми дочерними элементами этого селектора.

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

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

Некоторые другие свойства имеют больше смысланетпередаваться по наследству.

Подумайте о шрифтах: вам не нужно применятьfont-familyк каждому тегу вашей страницы. Вы устанавливаетеbodyшрифт тега, и все дочерние элементы наследуют его вместе с другими свойствами.

Вbackground-colorсобственность, с другой стороны, не имеет смысла передаваться по наследству.

Свойства, которые наследуют

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

  • border-collapse
  • border-spacing
  • caption-side
  • color
  • cursor
  • direction
  • empty-cells
  • font-family
  • font-size
  • font-style
  • font-variant
  • font-weight
  • font-size-adjust
  • font-stretch
  • font
  • letter-spacing
  • line-height
  • list-style-image
  • list-style-position
  • list-style-type
  • list-style
  • orphans
  • quotes
  • tab-size
  • text-align
  • text-align-last
  • text-decoration-color
  • text-indent
  • text-justify
  • text-shadow
  • text-transform
  • visibility
  • white-space
  • widows
  • word-break
  • word-spacing

Я получил это от этогохорошая статья Sitepointо наследовании CSS.

Принуждение свойств к наследованию

Что делать, если у вас есть свойство, которое не наследуется по умолчанию, и вы хотите, чтобы это было в дочерних элементах?

В дочерних случаях вы устанавливаете значение свойства в специальное ключевое словоinherit.

Пример:

body {
	background-color: yellow;
}

p { background-color: inherit; }

Принуждение свойств НЕ наследовать

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

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

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

Другие особые ценности

В добавок кinheritиrevertспециальные ключевые слова, которые мы только что видели, вы также можете установить любое свойство:

  • initial: используйте таблицу стилей браузера по умолчанию, если она доступна. В противном случае и если свойство наследуется по умолчанию, наследуйте значение. В противном случае ничего не делайте.
  • unset: если свойство наследуется по умолчанию, наследовать. В противном случае ничего не делайте.

Больше руководств по css:

Архитектура CSS — Веб-стандарты

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

Что интересно, обычно мы не упускаем из вида эту сторону, когда дело касается других языков. Разработчик на Rails не считается хорошим только потому, что его код работает по спецификации. Это считается базовым уровнем. Конечно, он должен работать по спецификации, но его качество измеряется другим: насколько код читаемый, легко ли его изменить или расширить, достаточно ли он отделён от других частей приложения, будет ли он масштабироваться?

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

Принципы хорошей архитектуры CSSСкопировать ссылку

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

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

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

ПредсказуемостьСкопировать ссылку

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

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

Повторное использованиеСкопировать ссылку

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

ПоддержкаСкопировать ссылку

Когда нужно добавить или изменить новые компоненты или возможности, это не должно приводить к рефакторингу существующего CSS. Добавление компонента А на страницу не должно своим появлением ломать компонент Б.

МасштабируемостьСкопировать ссылку

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

Распространённые ошибкиСкопировать ссылку

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

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

Изменение компонентов в зависимости от родителяСкопировать ссылку

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

.widget {
    background: yellow;
    border: 1px solid black;
    color: black;
    width: 50%;
}

#sidebar .widget {
    width: 200px;
}

body.homepage .widget {
    background: white;
}

На первый взгляд этот код выглядит вполне безобидно, но давайте проверим его на соответствие принципам, которые мы определили выше.

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

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

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

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

Части ПО (классы, модули, функции и т.п.) должны быть открыты для расширения, но закрыты для изменения.

Далее в статье мы рассмотрим, как изменять компоненты, не опираясь на родительский селектор.

Слишком сложные селекторыСкопировать ссылку

Удивительно, но эта статья обойдёт стороной демонстрацию всей мощи CSS-селекторов и не расскажет о том, как оформить целый сайт, не используя ни единого класса или ID.

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

#main-nav ul li ul li div { }
#content article h2:first-child { }
#sidebar > div > h4 + p { }

Все эти примеры логически верны. Первый, по-видимому, оформляет выпадающее меню, второй говорит, что заголовок в <article> должен выглядеть иначе, чем остальные элементы <h2>, а последний пример, скорее всего, добавляет отступ к первому абзацу в блоках боковой колонки.

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

Упомянутые примеры совсем не готовы для повторного использования. Поскольку селектор указывает на очень конкретную часть разметки, то как может другой компонент с иной структурой HTML использовать эти стили? Возьмём для примера первый селектор (выпадающее меню) — что, если похожее меню понадобится на другой странице, на которой не будет элемента #main-nav? Тогда вам придётся повторить все стили.

Эти селекторы также очень непредсказуемы в случае, когда меняется оригинальный HTML. Представим, что разработчик решил поменять тег <div> в третьем примере на <section> — в результате весь селектор развалится.

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

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

Слишком общие имена классовСкопировать ссылку

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

<div>
    <h4>…</h4>
    <div>
        Лорем ипсум…
        <button>Жми сюда!</button>
    </div>
</div>
.widget {}
.widget .title {}
.widget .contents {}
.widget .action {}

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

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

Слишком общие имена классов приводят к непредсказуемому CSS.

Когда правило делает слишком многоСкопировать ссылку

Однажды вы создаёте визуальный компонент, который должен отстоять на 20 пикселей от верхнего левого угла блока на вашем сайте:

.widget {
    position: absolute;
    top: 20px;
    left: 20px;
    background-color: red;
    font-size: 1.5em;
    text-transform: uppercase;
}

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

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

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

ПричинаСкопировать ссылку

Упомянутые выше проблемные примеры объединяет одна особенность: все они слишком полагаются на оформление CSS.

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

Простой ответ на этот вопрос «да», но, как обычно, всё не так просто. Разделять содержимое и представление хорошо, но содержимое не отделяется от представления только потому, что ваш CSS отделён от HTML. Скажем иначе: вы не достигнете цели, если просто уберёте всё представление из HTML, но при этом для работы вашего CSS потребуется подробнейшее знание структуры HTML.

Более того, HTML редко состоит только из содержимого, почти всегда в нём есть и структура. И часто эта структура состоит из контейнеров, единственной задачей которых является объединение некоторой группы элементов для работы CSS. Даже без презентационных классов такие структуры добавляют представление в HTML-код. Но действительно ли это смешивает содержимое с представлением?

Я уверен, что на текущем уровне развития HTML и CSS необходимо и зачастую разумно использовать HTML и CSS в качестве единого слоя представления. Слой содержимого в таком случае может быть отделён с помощью шаблонизаторов или подключаемых фрагментов (как partials в Ruby).

РешениеСкопировать ссылку

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

Лучший подход, который мне удалось найти, состоит в том, чтобы как можно меньше опираться на структуру HTML в CSS. CSS должен определять как выглядит набор визуальных элементов. Для минимизации влияния HTML эти элементы должны выглядеть ровно так, как они описаны, независимо от того, где они находятся в HTML. Если некоторые компоненты должны выглядеть по-разному в разных ситуациях, они должны быть вызваны по-другому, и отвечать за этот вызов должен HTML.

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

CSS определяет, как выглядит ваш компонент, а HTML применяет этот вид к элементам на странице. Чем меньше CSS «знает» про структуру HTML, тем лучше.

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

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

Несмотря на то, что эти сомнения справедливы, они могут привести к ошибочным выводам. Вывод такой: либо вы используете родительский селектор в CSS, либо вам придётся написать этот HTML-класс тысячу раз руками. Но, очевидно, есть и другие варианты. Уровень абстракции компонентов в Rails и других фреймворках легко позволяет явно описывать внешний вид прямо в HTML без необходимости снова и снова писать один и тот же класс.

Правильный подходСкопировать ссылку

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

Будьте точнееСкопировать ссылку

Лучший способ добиться того, чтобы ваши селекторы не влияли на ненужные элементы — это не дать им такой возможности. Со временем вы можете обнаружить, что селектор вроде #main-nav ul li ul li div применяется уже совсем не к тому элементу из-за изменившейся разметки. Класс .subnav, напротив, имеет очень мало шансов быть случайно применённым не к тому элементу. Назначать классы прямо элементам, которые вы хотите оформить — лучший способ сохранить ваш CSS предсказуемым.

/* Граната */
#main-nav ul li ul { }

/* Снайперская винтовка */
.subnav { }

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

Разделяйте ответственностьСкопировать ссылку

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

В общем случае компоненты должны определять свой внешний вид, а не раскладку и позиционирование. Будьте осторожны, когда видите свойства вроде background, color и font в одном правиле с position, width, height и margin.

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

Задайте пространство имёнСкопировать ссылку

Мы уже выяснили, почему родительские селекторы не всегда на 100% эффективны для ограничения действия и пересечения стилей. Гораздо лучший подход — добавить пространство имён к самим классам. Если элемент является частью визуального компонента, то каждый из классов его вложенных элементов должен использовать имя класса базового компонента в качестве пространства имён.

/* Высокий риск пересечения имён классов */
.widget { }
.widget .title { }

/* Низкий риск пересечения имён классов */
.widget { }
.widget-title { }

Добавление пространства имён к классам делает ваши компоненты самодостаточными и модульными. Это также уменьшает вероятность конфликтов с уже существующими классами и снижает специфичность, необходимую для оформления дочерних элементов.

Расширяйте компоненты модификаторами классовСкопировать ссылку

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

/* Плохо */
.widget { }
#sidebar .widget { }

/* Хорошо */
.widget { }
.widget-sidebar { }

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

Организуйте CSS в логическую структуруСкопировать ссылку

Джонатан Снук в своей замечательной книге SMACSS убеждает разделять CSS-правила на четыре отдельные категории: базовые, раскладку, модули и состояния. Базовые состоят из сбросов и умолчаний для элементов. Раскладка — для расположения глобальных элементов сайта, а также общих вспомогательных вещей вроде модульных сеток. Модули — это визуальные элементы для повторного использования и стили состояний для оформления того, что можно включить или выключить с помощью JavaScript.

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

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

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

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

Используйте классы строго для оформленияСкопировать ссылку

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

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

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

Тем не менее, устоявшиеся договорённости помогут полностью избежать этой проблемы. Когда вы видите класс в HTML, вы должны быть способны чётко сказать, для чего он предназначен. Мой совет — добавлять префикс ко всем неоформительским классам. Я использую .js- для JavaScript и .supports- для классов Modernizr. Все классы без префикса — для оформления и только для оформления.

Это позволяет искать неиспользуемые классы и удалять их из HTML простым поиском по папке со стилями. Вы можете даже автоматизировать этот процесс с помощью JavaScript, сравнивая классы в HTML с классами в объекте document.styleSheets. Классы, которых нет в document.styleSheets, можно безопасно удалять.

Итак, полезно разделять содержимое и представление, и столь же важно отделять представление от поведения. Использование классов с оформлением в качестве основы для JavaScript так сильно связывает CSS с JavaScript, что становится сложно или даже невозможно обновить оформление некоторых элементов, не сломав их поведение.

Логическая структура в именах классовСкопировать ссылку

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

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

/* Компонент */
.button-group { }

/* Модификатор компонента (изменяющий .button) */
.button-primary { }

/* Вложенный объект (находится внутри .button) */
.button-icon { }

/* Это класс компонента или раскладки? */
.header { }

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

/* Правила шаблонов (с использованием Sass) */
%template-name
%template-name--modifier-name
%template-name__sub-object
%template-name__sub-object--modifier-name

/* Правила компонентов */
.component-name
.component-name--modifier-name
.component-name__sub-object
.component-name__sub-object--modifier-name

/* Правила для раскладки */
.l-layout-method
.grid

/* Правила состояний */
.is-state-type

/* Классы для JavaScript без оформления */
.js-action-name

Переработанный первый пример:

/* Компонент */
.button-group { }

/* Модификатор компонента (изменяющий .button) */
.button--primary { }

/* Вложенный объект (находится внутри .button) */
.button__icon { }

/* Класс раскладки */
.l-header { }

ИнструментыСкопировать ссылку

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

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

ПрепроцессорыСкопировать ссылку

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

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

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

  • Никогда не вкладывайте правила только для организации кода. Вкладывайте только тогда, когда это нужно в CSS на выходе.
  • Никогда не используйте примеси (mixin), если не передаёте аргумент. Примеси без аргументов гораздо лучше использовать в качестве шаблонов, которые можно расширить.
  • Никогда не используйте @extend для селектора, который не является одиночным классом. Это не имеет смысла с точки зрения дизайна и раздувает скомпилированный CSS.
  • Никогда не используйте @extend для компонентов интерфейса в модификаторе компонента, иначе вы нарушаете цепь наследования (подробнее об этом дальше).

Лучшая часть препроцессоров — это функции, вроде @extend и %placeholder. Обе они позволяют просто управлять абстракциями в CSS, при этом не раздувая код и обходясь без добавления в HTML огромного количества базовых классов, с которыми потом очень сложно управиться.

@extend нужно использовать с осторожностью, потому что иногда эти классы будут нужны в HTML. Например, когда вы впервые узнаёте про @extend, то его сразу хочется применить ко всем классам-модификаторам как-то так:

.button {
    /* Стили кнопки */
}

/* Плохо */
.button--primary {
    @extend .button;
    /* Стили модификатора */
}

Проблема с этим подходом в том, что вы теряете цепь наследования в HTML. Теперь довольно сложно выбрать все экземпляры кнопки с помощью JavaScript.

Как правило, я не расширяю компоненты интерфейса или что-то другое, тип чего мне может пригодиться знать в будущем. Для этого случая как раз и придуманы компоненты, и это ещё один способ, помогающий отличать шаблоны от компонентов. Шаблон — это нечто, к чему вы никогда не обратитесь в логике вашего приложения, и поэтому его можно безопасно расширить с помощью препроцессора.

Как это может выглядеть на примере модального окна, о котором шла речь выше:

.modal {
    @extend %dialog;
    @extend %drop-shadow;
    @extend %statically-centered;
    /* Другие стили окна */
}

.modal__close {
    @extend %dialog__close;
    /* Другие стили кнопки закрытия */
}

.modal__header {
    @extend %background-gradient;
    /* Другие стили заголовка окна */
}

CSS LintСкопировать ссылку

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

CSS Lint указывает на проблемы в вашем CSS-коде. Он делает базовую проверку синтаксиса, а также применяет к коду набор правил, которые позволяют выделить в нём проблемные подходы или признаки неэффективности. Все правила расширяемы, потому вы легко можете написать свои или пропустить ненужные.

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

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

Основываясь на договорённостях, которые я предложил выше, очень легко написать правила для определения неверных подходов. Вот несколько правил, которые я использую:

  • Не допускайте ID в своих селекторах.
  • Не используйте несемантические типы селекторов (div и span, напр.) для любого неодиночного правила.
  • Не используйте больше двух комбинаторов в селекторе.
  • Не допускайте использование классов, начинающихся с .js-.
  • Внимание, если раскладка и позиционирование применяются в правилах для элементов без префикса .l- в названии класса.
  • Внимание, если класс, определённый сам по себе, позднее переопределяется как дочерний или иначе.

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

HTML InspectorСкопировать ссылку

Ранее я предположил, что будет довольно просто пройтись по вашим HTML-классам и всем подключенным стилям и выдать предупреждение, если класс был использован в HTML, но не определён ни в одном файле стилей. Сейчас я разрабатываю инструмент, который называется HTML Inspector, чтобы сделать этот процесс проще.

HTML Inspector проходит по вашему HTML и (почти как CSS Lint) позволяет вам написать собственные правила, которые вызывают ошибки или предупреждения, когда какие-то договорённости нарушаются. Сейчас я использую следующие правила:

  • Внимание, если один и тот же ID используется на странице два раза.
  • Не используйте классы, не упомянутые ни в одном из файлов стилей или передайте список разрешённых (с префиксом .js-, напр.)
  • Классы модификаторов не должны использоваться без их базовых классов.
  • Классы вложенных объектов не должны использоваться в отсутствие родительского базового класса.
  • Простые элементы <div> и <span> не должны использоваться в HTML без назначенных классов.

ЗаключениеСкопировать ссылку

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

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

Основные правила и принципы написания CSS

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

  • Легко поддерживаемые файлы стилей
  • Прозрачность и читаемость кода
  • Масштабируемость стилей

Несколько техник помогут нам достичь этих целей.

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

Содержание


Анатомия CSS-документа

Мы всегда должны стараться соблюдать принятое форматирование. Это означает согласованные комментарии, синтаксис и соглашение об именовании.

Общие моменты

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

Я предпочитаю отступы в четыре пробела и писать многострочный CSS.

Один файл или много файлов

Некоторые предпочитают работать с одиночными, большими файлами. Это хорошо и при следовании данному руководству у вас не прибавится проблем. Начав использовать Sass, я начал разбивать мои стили на множество маленьких, подключаемых через include. Это тоже хорошо… Как бы там ни было, правила и рекомендации, приведённые ниже, применимы к обоим способам. Единственное замечание относится к «Оглавлению» и «Названиям секций». Продолжайте читать, чтобы узнать подробности.

Оглавление

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

/*------------------------------------*\
    $CONTENTS
\*------------------------------------*/
/**
 * CONTENTS............You’re reading it!
 * RESET...............Set our reset defaults
 * FONT-FACE...........Import brand font files
 */

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

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

Названия секций

Оглавление будет бесполезно пока не будет соотноситься с названиями секций. Оформляйте секцию таким способом:

/*------------------------------------*\
    $RESET
\*------------------------------------*/

Знак $ префиксно дополняет название секции, позволяя искать по файлу такой шаблон $[НАЗВАНИЕ-СЕКЦИИ] и, таким образом, производить поиск только по названиям секций.

Работая с большим файлом стилей, оставляейте отступ в пять строк между секциями, вот так:

/*------------------------------------*\
    $RESET
\*------------------------------------*/
[Our
reset
styles]
 
 
 
 
 
/*------------------------------------*\
    $FONT-FACE
\*------------------------------------*/

Этот участок пустого пространство легко и быстро бросается в глаза при пролистывании большого файла.

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

Организация правил

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

Порядок правильно организованного файла стилей похож на это:

  1. Reset – сброс, платформа для написания кода стилей.
  2. Элементыh2, ul и подобные без указания классов.
  3. Объекты и абстракции — общие конструкции без дизайна.
  4. Компоненты – компоненты, построенные на объектах и их расширениях.
  5. Полезные стили – состояния ошибок и другое.

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

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

Анатомия CSS-правила

[Селектор] {
    [Свойство]:[Значение]
    [<-   Объявление  ->]
}    

Я руководствуюсь несколькими правилами при написании CSS-правил.

  • Дефис как разделитель (Исключая БЭМ запись, смотрите ниже)
  • Отступ в 4 пробела
  • Многострочность
  • Свойства сортируются в порядке релевантности (НЕ в алфавитном)
  • Выравнивайте свойства с вендорными префиксами так, чтобы их значения были друг под другом.
  • Используйте отступы в стилях, чтобы отразить структуру HTML.
  • Всегда заканчивайте объявление знаком точки с запятой

И сразу пример:

.widget{
    padding:10px;
    border:1px solid #BADA55;
    background-color:#C0FFEE;
    -webkit-border-radius:4px;
       -moz-border-radius:4px;
            border-radius:4px;
}
    .widget-heading{
        font-size:1.5rem;
        line-height:1;
        font-weight:bold;
        color:#BADA55;
        margin-right:-10px;
        margin-left: -10px;
        padding:0.25em;
    }

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

Также мы видим, что объявления селектора .widget-heading отсортированы в порядке релевантности; .widget-heading вероятнее всего текстовый элемент, поэтому мы начинаем правило с типографских свойств, за которыми уже следуют все остальные.

Единственное исключение в многострочном CSS может быть в таком случае:

.t10    { width:10% }
.t20    { width:20% }
.t25    { width:25% }       /* 1/4 */
.t30    { width:30% }
.t33    { width:33.333% }   /* 1/3 */
.t40    { width:40% }
.t50    { width:50% }       /* 1/2 */
.t60    { width:60% }
.t66    { width:66.666% }   /* 2/3 */
.t70    { width:70% }
.t75    { width:75% }       /* 3/4*/
.t80    { width:80% }
.t90    { width:90% }

В этом примере (из сеточной системы inuit.css) гораздо больше смысла использовать однострочные правила.

Соглашения об именовании

В большинстве случаев я использую дефис как разделитель слов в классах (например .foo-bar, не .foo_bar и не .fooBar), но в некоторых случаях я использую БЭМ-запись.

БЭМ — методология именования и категоризации CSS селекторов для приведения их в чёткий порядок, придания прозрачности и информативности.

Соглашение об именовании выражается следующим шаблоном:

.block{}
.block__element{}
.block--modifier{}
  • .block представляет собой наивысший уровень абстракции или компонента.
  • .block__element является вложенным элементом .block, формирующим .block как сущность.
  • .block--modifier — класс отражающий другое состояние или версию .block.

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

.person{}
.person--woman{}
    .person__hand{}
    .person__hand--left{}
    .person__hand--right{}

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

Теперь мы можем создавать селекторы, опираясь на базовые объекты и также без проблем понимаем, что делает каждый конкретный селектор; является ли он частью компонента (__) или же модификацией (--)?

Итак, .page-wrapper является отдельным селектором; он не формирует часть компонента и, значит, является валидным селектором. В противовес этому, селектор .widget-heading относится к компоненту; он является дочерним элементом .widget и поэтому мы вынуждены переименовать этот класс в .widget__heading.

БЭМ непригляднее и перегруженней, но, тем не менее, он предоставляет огромные возможности, с помощью которых мы можем определить назначение и отношения элементов просто посмотрев на их классы. Также, БЭМ обычно сжимается c помощью gzip, после использования минификаторов, которые первоклассно работают с повторениями.

Независимо от того, используете вы БЭМ или нет, всегда заботьтесь о грамотном именовании классов; классы должны быть короткими, насколько это возможно, но настолько длинными, насколько это необходимо. Убедитесь, что абстракции имеют очень общие классы (например .ui-list, .media) для возможного переиспользования. Расширения абстракций должны иметь гораздо более конкретные классы (например .user-avatar-link). Не беспокойтесь о длинных классах; gzip выполнит свою работу потрясающе хорошо.

Классы в HTML

Для большей читаемости разделяйте классы в разметке двумя (2) пробелами:

<div>

Увеличенные отступы между классами позволят легко вычленять отдельные классы.

JS-классы

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

Если вам требуется привязать к вёрстке какую-то логику, используйте специальный JS-класс — обычный класс, дополненный префиксом .js-, например .js-toggle, .js-drag-and-drop. Данный приём позволяет добавлять JS- и CSS-классы, без создания самому себе проблем в будущем, а также разделяет логику поведения и оформление страницы друг от друга.

<th>
</th>

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

Интернационализация

Несмотря на то, что я британский разработчик и привык писать colour вместо color, считаю, что для улучшения однородности лучше использовать американский английский при написании CSS. CSS, как и другие (если не все) языки, написан на американском английском, так что сочетание color:red; с классами .colour-picker{} вредит однородности кода. Я ранее предлагал и отстаивал написание селекторов на двух языках, например:

.color-picker,
.colour-picker{
}

Тем не менее, работая недавно над очень большим Sass-проектом, в котором было множество colour-переменных (например, $brand-color, $highlight-color и т.д.), я осознал, что поддержка двух версий каждой переменной очень скоро становится утомительна. Это также означает в два раза больше работы с такими вещами, как поиск и замена.

Для однородности всегда называйте классы и переменные на той локализации языка, которая в нём принята.

Комментарии

Я использую комментарии в стиле docBlock, которые я ограничиваю в 80 символов:

/**
 * Пример комментария в стиле docBlock
 *
 * Более длинное описание комментария, описывающего код в больших
 * подробностях. Комментарии ограничиваются в 80 символов.
 * 
 * Можно вставлять разметку в комментарии. Делается это так:
 * 
   <div class=foo>
       <p>Lorem</p>
   </div>
 * 
 * Разметка префиксно не дополняется звездочками, чтобы оставить возможность
 * легкого копипаста.
 * 
 */

Вы должны документировать и комментировать так много, насколько возможно; всё, что кажется вам прозрачным и говорящим за себя, может не быть таковым для другого разработчика. Пишите кусок кода и сразу после этого объясняйте его.

Комментарии на стероидах

Существуют несколько продвинутых техник, связанных с комментариями:

  • Квази-селекторы
  • Теги в коде
  • Ссылка на расширяемый компонент
Квази-селекторы

Вы никогда не должны перегружать селектор; скажем так, вы никогда не должны писать ul.nav{}, если вы можете написать просто .nav{}. Перегрузка селекторов приводит к уменьшению производительности селекторов (увеличению времени рендеринга страницы), исключает возможность потенциального переиспользования селектора для элемента другого типа и увеличивает специфичность селектора. Это все те вещи, которые должны избегаться при любых условиях.

Иногда бывает полезно сообщить следующему разработчику, в каком контексте вы собираетесь использовать селектор. Давайте рассмотрим .product-page. Этот класс выглядит так, как будто должен использоваться с корневыми элементами, такими как html и body, но глядя только на .lists и найдёт объекты .nav и .matrix (и, возможно, больше).

Ссылки между объектом и его расширением

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

В вашем основном файле стилей:

/**
 * Extend `.foo` in theme.css
 * (Дополнен классом `.foo` в theme.css)
 */
 .foo {}

В вашем файле стилей темы:

/**
 * Extends `.foo` in base.css
 * (Дополняет класс `.foo` из base.css)
 */
 .bar{}

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


Напиcание CSS

Предыдущая часть раскрывает, как мы структурируем и форматируем наш CSS; здесь существуют более-менее чёткие правила.

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

Создание новых компонентов

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

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

OOCSS

Я использую OOCSS подход; Я разделяю компоненты на структуру (объекты) и оформление (расширения). Как аналогию (не пример) можно рассмотреть следующее:

.room{}

.room--kitchen{}
.room--bedroom{}
.room--bathroom{}

Мы располагаем комнатами нескольких типов, но все комнаты имеют похожие свойства; в каждой комнате есть пол, потолок, стены и двери. Мы можем обобщить эту информацию в общем классе .room{}. Тем не менее, у нас есть специальные отличающиеся друг от друга типы комнат; кухня должна иметь плитку на полу, спальня — ковёр; в ванной не должно быть окна, а в спальне, напротив, должно. В каждой комнате скорее всего стены покрашены в свой цвет. OOCSS учит нас абстрагировать похожие свойства в базовый объект и в дальнейшем дополнять его с помощью расширяющих классов для добавления особенных качеств.

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

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

Разметка

Все компоненты должны быть полностью независимы от ширины; они должны оставаться резиновыми и их ширина должна контролироваться их обёрткой или системой модульных сеток.

Высота никогда не должна назначаться элементам. Высота применяется только на сущности, имевшие размеры до того, как попали на сайт (например, картинки и спрайты). Никогда не устанавливайте высоту на p, ul, div, ни на что. Часто вы можете добиться желаемого эффекта при помощи гораздо более гибкого line-height.

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

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

Единицы измерения

Я использую сочетание методов задания размеров интерфейса: проценты, пиксели, ems, rems или вообще не задаю единицы измерения.

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

Размеры шрифтов я устанавливаю в rem c запасным решением с использованием пикселей. Этот метод предоставляет доступность контента как с em и уверенность при использовании пикселей. Вот простой Sass-миксин для одновременной работы с пикселями и rem (вы должны определить переменную $base-font-size ранее в стилях):

@mixin font-size($font-size){
    font-size:$font-size +px;
    font-size:$font-size / $base-font-size +rem;
}

Я использую пиксели только для элементов, имеющих размеры и вне контекста сайта — в основном, это картинки и спрайты, чьи размеры изначально заданы в этих единицах.

Размер текста

Я составил список классов (похожих на модульную сетку) для задания размера текста. Эти классы могут быть использованы стилизации текста в двухцепочечной иерархии. Моя статья «Pragmatic, practical font-sizing in CSS» расскажет вам, как это работает.

Сокращённая запись

Сокращённую запись следует использовать с осторожностью.

Это может показаться заманчивым использовать правила похожие на background: red;, но делая это, мы на самом деле говорим: «Я хочу, чтобы фоном не было скролящейся, находящейся сверху-слева и повторяющейся по горизонтали и вертикали картинки и чтобы цвет фона был красный». В девяти случаях из десяти это не вызовет никаких проблем, но в 10% обязательно доставит достаточно неприятностей, чтобы не использовать сокращенные записи. Вместо этого используйте background-color: red;.

Например, ситуация с правилом margin: 0; — оно ясное и короткое, но черезчур точное. Если вы на самом деле хотите воздействовать на нижний отступ элемента, то гораздо более подходяще будет использовать margin-bottom: 0;.

Старайтесь сохранять чёткое представление о свойствах, которые вы устанавливаете и следите за тем, чтобы случайно не сбросить свойства других элементов, используя сокращенную запись. Например, если вы хотите сбросить нижний отступ, то нет никакой необходимости в сбрасывании всех отступов с помощью margin: 0;.

Сокращённая запись хороша, но ей легко злоупотреблять.

Идентификаторы

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

НИКОГДА не используйте идентификаторы в CSS.

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

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

Селекторы

Сохраняйте селекторы короткими, эффективными и переносимыми.

Тяжелые, глубоко вложенные селекторы никуда не годятся по ряду причин. Например возьмем .sidebar h4 span {}. Этот селектор сильно привязан к существующей разметке и поэтому нет возможности переместить span из h4 и из .sidebar, следовательно, нет возможности обеспечить поддержку стилей на должном уровне.

Слишком длинные селекторы также вызывают проблемы производительности; чем больше проверок в селекторе (например, селектор .sidebar h4 span имеет три проверки, а .content ul p a — четыре), тем больше работы выполняет браузер.

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

Селекторы в основном должны быть короткими (например, состоящими из одного класса), но имена классов должны быть настолько длинными, насколько это требуется. Класс .user-avatar намного лучше, чем .usr-avt.

Запомните: Классы на самом деле ни семантичны, ни не семантичны; они могут использоваться рационально или нерационально! Перестаньте беспокоиться о «семантике» имён классов и выберите что-нибудь рациональное и безопасное в будущем.

Перенасыщенные селекторы

Как говорилось выше, увидеть специфичный селектор — всегда плохой знак.

Перенасыщенный (гиперспецифичный) селектор это такой, как div.promo. Скорее всего, мы можем достичь тот же самый эффект, используя лишь .promo. Конечно, иногда мы хотим указать зависимость класса от элемента (например, если у вас есть общий класс .error, который должен выглядеть по разному при разных элементах (например, .error { color: red; } div.error { padding: 14px; })), но по возможности избегайте этого, где это только возможно.

Другим примером слишком перенасыщенного селектора может быть ul.nav li a {}. Как описано выше мы сразу можем выкинуть ul, и так как мы знаем, что .nav это список, то ссылка будет вложена только в li, поэтому мы можем сократить ul.nav li a {} до .nav a.

Производительность селекторов

Хоть это и правда, что браузеры только улучшают свои показатели в скорости рендеринга CSS, эффективность — это то, на чём мы можем быть сфокусированы всегда. Короткие, не вложенные селекторы, избежание универсального (* {}) селектора, как основного, и избежание больших комбинаций CSS3-селекторов должны помочь обойти проблемы производительности.

Последовательность CSS-селекторов

Вместо использования селекторов, спускающихся по всему DOM-дереву, чаще удобнее добавить требуемому элементу класс. Давайте рассмотрим конкретную ситуацию на примере .header ul{}

Давайте представим, что ul действительно главная навигация на вашем сайте. Этот элемент находится в шапке сайта, как вы и ожидаете, и при этом не повторяется; .header ul{} будет работать, но он не идеален и не рекомендуем. Этот селектор небезопасен в будущем и, конечно, недостаточно точен. Проблема станет очевидна так скоро, как вы добавите ещё один ul в шапку сайта — новый элемент унаследует все стили нашего главного меню, и шансы, что мы так и задумали, весьма невелики. Это приведёт к вынужденному рефакторингу большого количества кода или отмене большинства стилей для второго ul, чтобы уничтожить последствия недостаточно специфичного селектора.

Составляющие селектора должны отвечать причинам стилизации чего-либо; спросите себя «Я пишу этот селектор именно, потому что ul вложен в .header или из-за того, что этот элемент — это главное меню на моём сайте?». Ответ опреляет правильный селектор.

Убедитесь, что ключевые элементы селектора не являются простыми селекторами элемента/типа или классами объекта/абстракции. Вы никогда не должны писать селекторы похожие на .sidebar ul{} или .footer .media{} в вашем файле стилей темы.

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

Для полного объяснения прочитайте мою статью Shoot to kill; CSS selector intent

!important

Допустимо использовать !important только на вспомогательных классах. Превентивно добавлять !important удобно и полезно, например, если вы знаете, что селектор .error { color: red !important; } всегда должен нуждаться в наибольшем приоритете.

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

Магические числа и абсолютные значения

Магическое число — число используемое лишь потому, что «это просто работает». Это порочная практика, так как очень редко она работает по какой-либо реальной причине и обычно достаточно недальновидна, негибка и причина появления самого числа вероятнее всего забудется. Магические числа устраняют симптомы, но не никак не влияют на проблему.

Например, использование .dropdown-nav li:hover ul { top: 37px; }, чтобы расположить выпадающее меню внизу навигации не принесёт ничего хорошего, так как 37px магическое число. Оно работает только потому, что в этом конретном сценарии элемент .dropdown-nav оказался высотой в 37 пикселей.

Вместо этого мы должны использовать .dropdown-nav li:hover ul { top: 100%; }, что означает: вне зависимости какой высоты будет меню dropdown-nav, выпадающее всегда будет сдвинуто на 100% от верхней границы родителя.

Каждый раз, когда вы жёстко задаёте число, подумайте дважды; если вы можете избежать этого — избегайте, например, используя ключевые слова или синонимы (top: 100%; для того, чтобы сдвинуть на 100% от верха) или — даже лучше — не используя никаких единиц измерений.

Каждое установленное вами числовое значение, скорее всего, было необязательным.

Стили в условных комментариях

Использования отдельных файлов стилей для IE, по большому счёту, можно избежать. Исключением может быть необходимость восполнить вопиющие недостатки поддержки различных свойств (например, PNG с альфа–каналом в IE6).

Главное правило: вся разметка и box-model правила могут и будут работать без дополнительных файлов стилей, если вы отрефакторите и переработаете ваш CSS. Это означает, что мы никогда не будем рады, если увидим <!--[if IE 7]> element{ margin-left:-9px; } < ![endif]--> или любой подобный CSS, используемый лишь для того, чтобы «заставить что-то работать правильно».

Отладка

Если вы столкнулись с проблемой в CSS, то удаляйте куски кода, до того как начать добавлять новые правила в попытке решить проблему. Проблема кроется в уже написанном CSS, написать ещё больше стилей — не самое верное решение!

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

Это бывает достаточно удобно добавить overflow: hidden; нужному элементу, чтобы избавиться от результатов кривой вёрстки, но overflow сам по себе вряд ли был проблемой; исправляйте проблему, а не её симптомы.

Препроцессоры

Sass — мой выбор среди препроцессоров. Используйте его с умом Используйте Sass, чтобы сделать ваш CSS более мощным, но избегайте вложенности, как чумы! Используйте вложенность только тогда, когда это действительно могло бы быть необходимо в чистом CSS, например:

.header{}
.header .site-nav{}
.header .site-nav li{}
.header .site-nav li a{}

Это было бы полностью избыточно в нормальном CSS, следовательно, следущий Sass-код будет плох:

.header{
    .site-nav{
        li{
            a{}
        }
    }
}

Иcпользуя Sass, пишите это так:

.header{}
.site-nav{
    li{}
    a{}
}

Источник: Основные правила и принципы написания CSS

Полное руководство по всем единицам измерениям CSS

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

Теперь, несмотря на то, что CSS не является языком программирования (разберитесь с этим), его все еще так характеризуют. Особенно в последние годы я бы сказал, что функции CSS выросли до такой степени, что их использование без «поиска в Google», автозаполнения или других справочных материалов довольно сложно.

Среди этих растущих особенностей CSS — его система единиц измерения. Давно прошли времена «идеальных по пикселям» дизайнов, в которых использовались единицы измерения px, и теперь они являются относительными, позволяя разработчикам создавать адаптивные дизайны для множества форм-факторов современных устройств.

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

Абсолютные единицы

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

Практический курс по верстке адаптивного сайта с нуля!

Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3

Узнать подробнее

px

Наиболее часто используемый из группы. Хотя px обычно ассоциируется с пикселем, из-за аббревиатуры, он не обязательно равен одному пикселю на экране. Означает ли это, что px на самом деле не абсолютны? Ну, вроде да, но в то же время и нет.

Это единица измерения, специально разработанная для CSS, и ее реальное значение зависит от «разрешения» экрана или принтера, также известной как PPI (пикселей на дюйм) или DPI (точек на дюйм) соответственно. В этом плане это несколько относительно. Используя экраны разного разрешения и одинаковых размеров, чтобы убедиться в этом — вы увидите, что независимо от разрешения, px должны выглядеть одинаково.

Тем не менее px, это не лучшая единица измерения для создания адаптивного дизайна. Это относительно PPI / DPI, но это только гарантирует, что он будет выглядеть одинаково при разном разрешении экрана. Это не связано с каким-либо конкретным значением, которое может быть установлено разработчиком. Это, безусловно, будет полезно для установки, например, основных font-size или минимальных / максимальных размеров элемента, но вы не должны злоупотреблять ими.

cm / mm / in

Здесь я собрал 4 единицы, так как они имеют некоторые общие свойства. Все они обычно используются в реальных измерениях. Из-за этого они, в основном, подходят для стилизации веб-сайта для печати (согласно правилу @media print {}), а не непосредственно для просмотра на экране.

Хотя использование этих единиц для печати должно привести к относительно правильному представлению в реальном мире, то же самое не относится к их использованию на экранах. Поэтому, если вы поместите линейку на экран (не делайте этого), не ожидайте, что элемент с width 1cm будет соответствовать реальному размеру 1 см.

Тем не менее, есть возможность выполнить некоторые математические вычисления, чтобы отобразить на экране «настоящие» см: 1in = 2.54cm = 25.4mm = 101.6q = 96px

Примечание: я также добавил q (четверть миллиметра) в сравнение, которая равна 1/4 мм — очень непопулярная единица, использование которой не рекомендуется — для экранов, принтеров и т.д.

И вот некоторые доказательства, подтверждающие эти расчеты:

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

pt / pc

Наконец, у нас есть 2 очень разных единицы по сравнению с тем, что мы уже видели: pt (points) и pc (picas).
Эти единицы в настоящее время широко не используются ни в виртуальном, ни в реальном мире, хотя они уходят корнями к типографическому дизайну. Может быть, поэтому они, в основном, используются с такими свойствами, как font-size.

Что касается математики и визуализации: 6pc = 72pt = ~ 1in

Относительные единицы

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

%

Начнем с самой узнаваемой относительной единицы — процента %. В CSS все, что использует эту единицу, относится к:

Родителю (общее правило).

Последнему родительскому элементу, для которого значение position установлено relative, когда значние элемента установлено absolute.

Корневому элементу, когда для position устанавливается fixed.

Однако с этим есть несколько подводных камней, например, при задании значения width или height в процентах не работают, когда размеры родительского элемента определяются автоматически (установлены auto или не установлены вообще).

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

ex / ch

Далее у нас есть ex и ch- очень специфические единицы, которые действительно полезны только при работе с моноширинными шрифтами.

ex соответствует «x-height» текущего шрифта, где «x-height» означает высоту строчного x символа. С другой стороны, ch соответствует ширине символа 0. Таким образом, в обоих случаях мы имеем дело с измерением размера символа по оси x или y. Если вам интересно — да, на эти единицы влияет элемент font-size.

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

ex, как % и другие, все абсолютные единицы поддерживаются практически повсеместно, немного хуже ситуация с ch, но поддержку все же можно считать отличной (почти 98%):

Поддержка единицы ch по данным caniuse.com

Для шрифта Nunito, который используется на этом веб-сайте, с размером шрифта 17px или 16px зависимости от размера области просмотра, здесь вы можете увидеть эти единицы в действии:

Практический курс по верстке адаптивного сайта с нуля!

Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3

Узнать подробнее

em / rem

Наконец, мы дошли до моих любимых – em и rem. Если вы когда-либо создавали современный адаптивный веб-сайт, значит, вы слышали о них и, скорее всего, использовали их.

em является относительной единицей, или я должен сказать равной элементу font-size. Так что, если font-size задан 16px, это значение 1em. Таким образом, эти единицы идеально подходят для масштабируемых проектов, а также имеют отличную поддержку браузера.

Однако с em может быть сложно справиться, так как font-size передается дочерним элементам каждый раз, когда он устанавливается. Из-за этого вы можете быстро потерять представление о том, чему на самом деле равно font-size (особенно при установке самого font-size с помощью em, делая его относительно родительского font-size). И вот тут-то и вмешивается rem.

rem (он же root em) похож на своего старшего брата em в том смысле, что он относителен font-size, но только для корневого элемента (того, который представлен <html> тегом). Использование rem в проектах позволяет вам контролировать все размеры на веб-сайте с помощью одного единственного свойства. Он имеет немного худшую поддержку, чем em, но это также то, на что я лично полагаюсь и называю лучшей относительной единицей в CSS.

Поддержка rem по данным caniuse.com

Вот пример того, как em и rem с любым font-size 17px или 16px зависит от размера области просмотра. Имейте в виду, что этот font-size установлен только на верхнем уровне веб-сайта, поэтому не удивляйтесь, что они выглядят одинаково.

vh / vw / vmin / vmax

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

Легко понять, что на самом деле означает каждая из этих единиц, просто взглянув на их названия. В каждом из них (vh, vw, vmin, vmax) часть v, как уже упоминалось, означает «окно просмотра» (область — важнейшая составляющая относительности единиц). Все относится к тому, какая именно единица измерения области просмотра, относится к — высоте, ширине, меньшему и большему размеру соответственно.

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

Поддержка единиц области просмотра по данным caniuse.com

Что касается некоторых примеров — ниже вы должны увидеть 2 пары полос одинаковой ширины, которые зависят от вашего окна просмотра:

Другие единицы

Мы рассмотрели все единицы длины CSS (по крайней мере, из того, что я знаю), но есть и другие виды единиц CSS, которые мы должны изучить!

Время: s / мs

Единицы времени в CSS — секунды (s) и миллисекунды (ms) используются со свойствами, которые требуют от вас указания продолжительности чего-либо, например, animation или transition (и их «подсвойств»).

Это невозможно продемонстрировать с помощью столбцов, поэтому я оставлю вам только математику, которую вы почти наверняка уже знаете: 1s = 1000ms

Угол: deg / rad / grad / turn

В CSS мы также можем столкнуться с ситуациями, когда нам нужно установить какой-то угол. Для случаев, когда в transform применяют вращение или CSS градиенты, могут быть использованы единицы deg, rad, grad, и turn. Самый популярный из них – deg означает градусы, как мы все знаем. Остальные три также используются в реальном мире — радианы, градиенты и повороты (вращения на 360 градусов).

В целом, я рекомендую придерживаться deg, возможно, вы можете использовать rad и grad, если они действительно соответствуют вашим конкретным потребностям (например, значения, полученные из вычислений в JavaScript). Повороты действительно удобны, но они не так популярны, как градусы, поэтому лучше придерживаться того, что известно.

Что касается математики: 360deg = 400grad = 1turn = ~ 6.28rad

Советы по синтаксису единиц измерения

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

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

Вы можете прикреплять единицы для целых чисел и чисел с плавающей запятой, например, 1cm, -1px, 1.5s, когда данное значение имеет смысл (не добавляйте, например, -1s).

Значению может предшествовать минус (-), а также плюс (+), если вам это нравится, поэтому оба значения +1rem и -2em являются действительными.

Имена единиц не чувствительны к регистру, поэтому вы можете указать их как 1tUrN или 1REM, но разумной практикой является сохранение всех их в нижнем регистре.

Между значением и обозначением единицы не допускается пробел.

Безразмерные единицы – 0 не разрешены для единиц измерения времени.

Заключение

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

Тем не менее, я придерживаюсь основ, и для меня набор px, rem, %, ms и deg — это все, что мне нужно, и все, что я действительно использую для создания дизайнов. Возможно, я время от времени, добавляю единицу окна просмотра, когда имею дело с определенными элементами, но это действительно все.

Какой у вас «стандартный» набор единиц CSS? Узнали ли Вы что-то нового, чего не знали раньше? Вы хотите видеть больше таких простых, но интересных постов в блогах? Дайте мне знать в комментариях ниже! Спасибо за чтение и удачного кодирования!

Автор: Arek Nawo

Источник: areknawo.com

Редакция: Команда webformyself.

Практический курс по верстке адаптивного сайта с нуля!

Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3

Узнать подробнее

PSD to HTML

Верстка сайта на HTML5 и CSS3 с нуля

Смотреть

position в CSS | Учебные курсы

Свойство position — это универсальное и мощное свойство. Оно позволяет установить или изменить положение элемента и содержит четыре возможных значения:

  • static (значение по умолчанию)
  • relative
  • absolute
  • fixed

Часто используется наряду с четырьмя свойствами координат:

static

Это значение position по умолчанию: статичные элементы просто следуют естественному потоку. Любые значения left, right, top или bottom не оказывают влияния.

relative

Когда position установлено относительно, элемент может перемещаться относительно его текущей позиции.

HTML

<p>Едва мы спрятали лодку, Джа увлёк меня в джунгли, и вскоре мы 
   вышли на узкую, хорошо утоптанную тропу.</p>
<p>Я ринулся вверх, пытаясь в последнем усилии 
   дотянуться до руки Джа, но ситик с такой силой рванул копьё на себя, 
   что оно вырвалось из рук мезопа, едва не сорвавшегося со скалы, 
   а я, всё ещё цепляясь за древко, полетел вниз, прямо в 
   раскрытую пасть зверюги.</p>
<p>Он уже перешёл на бег, замахиваясь на ходу тяжёлым копьём.</p>

CSS

p { border: 1px solid blue; }

Давайте переместим второй абзац:

.second { position: relative; border-color: red; left: 20px; top: 10px; }

Красный абзац переместился на 20px слева направо и на 10px сверху вниз относительно его естественного положения, где он полагался быть.

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

absolute

Когда position устанавливается абсолютно, элемент может перемещаться относительно первого позиционированного предка.

Позиционированного? Что такое позиционированный элемент?

Позиционированный элемент — это тот, у которого значение position установлено как relative, absolute или fixed. Таким образом, если положение не задано статичным, то элемент позиционированный.

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

Давайте представим простую иерархию:

HTML

<section>
  Я позиционирован относительно.
  <p>
    Я позиционирован абсолютно!
  </p>
</section>

CSS

section {
  background: gold;
  height: 200px;
  padding: 10px;
  position: relative; /* Превращает <section> в точку отсчёта для <p> */
}

p {
  background: limegreen;
  color: white;
  padding: 10px;
  position: absolute; /* Делает <p> свободно перемещаемым */
  bottom: 10px; /* 10px снизу */
  left: 20px; /* 20px слева */
}

Жёлтый раздел имеет высоту 200px, а позиционирование задано как relative, что превращает его в точку отсчёта для всех дочерних элементов.

Зелёный абзац позиционирован как absolute и может свободно перемещаться относительно жёлтого раздела. Установив оба значения left и bottom, мы переместим его в левый нижний угол.

Что произойдёт, если мы одновременно установим left и right?

Если ширина не задана, применение left: 0 и right: 0 растягивает элемент на всю ширину. Это эквивалент установки left: 0 и width: 100%.

Если ширина установлена, то значение right отбрасывается.

fixed

Когда position задано как fixed, оно действует как абсолютное: вы можете установить координаты слева/справа и сверху/снизу.

Единственное отличие состоит в том, что точкой отсчёта является окно просмотра. Это означает, что фиксированный элемент не перемещается со страницей, он фиксируется на экране.

Что означает CSS?

CSS

Каскадная таблица стилей

Вычисления »Расширения файлов — и многое другое …

Оцените его:
CSS

000 Система скрепления содержимого

Сообщество »Цензура фильмов — и многое другое …

Оцените:
CSS

Поддержка боевой службы

Правительство» Военное дело

Оцените:
CSS

CSS Industries, Inc.

Бизнес »Символы NYSE

Оцените:
CSS

Колледж социальных наук

Академический и научный» Колледжи

Оцените:
CSS

Католические социальные службы

Сообщество »Религия

Оцените:
CSS Оценить:
CSS

Система обслуживания клиентов

Вычислительная техника» Telecom

CSS Оцените его:
CSS

Конфедеративные государства Корабль

Оцените его:
CSS

Система скремблирования содержимого

Разное »Funnies

Оцените его:
Оцените:
CSS

Core System Software

Computing» Программное обеспечение и многое другое…

Оцените:
CSS

Central Superior Services

Сообщество и многое другое …

CSS

Масштаб кривизны Пространство

Академия и наука »Любительское радио

Оцените его:
Оценить:
CSS

Услуги компьютерной поддержки

Бизнес» Общий бизнес

CSS

Col Орнальные символы стиля

Вычислительная техника »Общие вычисления

Оцените ее:
CSS

Client Security Software

Computing» Cyber ​​& Security — и многое другое…

Оцените:
CSS

Commissione della Sicurezza sociale e della Sanità

Международный »итальянский

CSS

Китайский Surface-to-Surface

Правительственный »Военный

Оцените его:
CSS

Услуги программного обеспечения Callist »Компании и фирмы

Оцените:
CSS

Сотовая связь с коммутацией каналов

Вычислительная техника» Сети

CSS

Углеродистая конструкционная сталь

Бизнес »Продукция

Оцените:
CSS

Поиск предложений по корпусу

Академические и научные» Библиотеки

4

Оцените его: