То, что отличает начинающих CSS-дизайнеров – неумелое использование селекторов (и как следствие этого - идиотически перегруженный HTML).

В этой заметке я попробую кратко рассказать, какие бывают селекторы, и как пользоваться наследованием и каскадом для того, чтобы указателей класса/ID в документе было меньше, а CSS был гораздо более “всеобъемлющим”.

Итак, приступим.

Что такое селектор? Это часть стилевого правила, указывающая, какие элементы это правило затронет.

Как известно, CSS версий 1 и 2 позволяет выбирать элементы из HTML-документа по имени элемента (тегу), классу элемента (атрибуту class), и идентификатору элемента (атрибуту id).

Следовательно, базовые селекторы таковы:

/* Выбрать все элементы класса info */
.info {
    color: gray;
}

/* Выбрать все элементы h2 (заголовки второго уровня) */
h2 {
    margin-left: 1em;
}

/*Выбрать любой элемент с идентификатором banner */
#banner {
    background: red;
}

Соответственно начинающие разработчики часто создают такую структуру:

 <ul>
     <li class='newshead'>
        <a class='link' href='?id=451'>Путин отмечал победу</a>
    </li>
    <li class='newshead'>
        <a class='link' href='?id=452'>Путин вручал Патриарху орден</a>
    </li>
    <li class='newshead'>
        <a class='link' href='?id=453'>Путин отдыхал за городом</a>
    </li>
    <li class='newshead'>
        <a class='link' href='?id=454'>Путин посетил провинцию</a>
    </li>
</ul>

не без резона полагая, что все элементы li будут отформатированы как указано селектором класса newshead.

Так вот, это дурь.

Специфичные селекторы (следите за пробелами!):

/* Выбрать все элементы h2 (заголовки второго уровня), 
    имеющие класс middle */
h2.middle {
    color: blue;
}

/* Выбрать ТОЛЬКО элемент h1, 
    имеющий идентификатор banner */
h1#banner {
    color: red;
}

/* Выбрать ТОЛЬКО элемент h1, 
    имеющий идентификатор banner и класс middle */
h1#banner.middle {
    padding: 10px;
}

Но и это еще не все. Как известно, селекторы CSS контекстные - то есть можно указывать не только свойства выбираемых элементов, но и внутри каких элементов они должны находится.

Скомбинируем таким образом простейшие селекторы:

/*     Выбрать только элементы LI (элементы списка),
     находящиеся в ЛЮБОМ элементе с инедтификатором left */
#left li {
    margin-left: 10px;
}

/*     Выбрать только элементы списка, находящиеся
     внутри НЕНУМЕРОВАННОГО списка класса headers */
ul.headers li {
}

/*    Выбрать только выделения b внутри заголовка второго уровня
     с идентификатором main, находящегося внутри любого элемента
     класса index (не забываем, что BODY - тоже элемент 
    и он может иметь класс и идентификатор! */
.index h2#main b {
}

Ну и самое полезное, пожалуй - селекторы можно указывать последовательно:

/*     Присвоить ВСЕМ заголовкам красный цвет  фона
    и левый отступ в 1em  (одну круглую шпацию)
    Поскольку буквы уменьшаются с уровнем заголовка 
    мы получим забавную “лесенку” */
h1, h2, h3, h4, h5, h6, h7 {
    margin-left: 1em;
    background: red;
}

/*Присвоить ВСЕМ заголовкам класса title  
    внутри элемента DIV с идентификатором inside серый цвет фона */
div#inside h1.title,
div#inside h2.title,
div#inside h3.title,
div#inside h4.title,
div#inside h5.title,
div#inside h6.title,
div#inside h7.title {
    background: gray;
}

В чем здесь соль? В том, что мудро используя селекторы количество используемых в коде HTML “крючков” для наложения стилей можно сократить в разы, просто используя семантику документа. Например, возьмем такой код:

<div id="nav">
    <ul>
        <li id='current'>Путин как будущее России</li>
        <li><a href='/news'>Новости о Путине</a></li>
        <li><a href='/about'>Биография</a></li>
        <li><a href='/catalog'>Ключевые тезисы</a></li>
    </ul>
    <p>И все это -  он, наш любимый президент.</p>
    <p class='bigger'>Обратите вниманиа на наше 
        <a href='/special'>послание Федеральному Собранию</a></p>
</div>

Итак, приводим предельно специфичные селекторы К КАЖДОМУ из элементов, указанных в этом сегменте (это без учета селектора через знак >, не поддерживаемого тупым IE):

/* Контейнер */
div#nav {
}

/* Список */
div#nav ul {
}

/* Элементы списка */
div#nav ul li {
}

/*Ссылки внутри списка и их состояние hover (ролловер) */
div#nav ul li a {
}

div#nav ul li a:hover {
}

/*     Элемент списка с идентификатором current 
    (например, пункт меню, активного в настоящий момент */
div#nav li#current {
}

/* Все параграфы */
div#nav p {
}
/* Параграф с классом bigger */
div#nav p.bigger {
}
/* Ссылка внутри параграфа класса bigger */
div#nav p.bigger a{
}

Смените идентификатор элемента DIV, например, на “newnav” - и все вышеуказанные селекторы уже не будут применены ни к нему, ни к элементам внутри него.

Присвойте body класс, например, “info”, создайте копию этих селекторов и припишите в их начало .info - и на странице с body класа info вид всего этого блока будет другим.

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

Немного полезной информации для любознательных:

  • Информация о других интересных селекторах, само собой лишь частично поддерживаемых IE - таких как селектор последовательности (+), селектор всех элементов (*), селектор прямого потомка (>) и селектор атрибута.
  • SelectOracle переводит селекторы любой сложности (включая селекторы CSS3) на понятный английский язык.

###Другие части этой интересной истории