- Введение
- Селекторы
- Специфичность
- Важность
- Наследование
- Каскад
- Значения и единицы измерения
- Добавление CSS на страницу
- Типы устройств
- Ссылки
- Книги
Введение ⇡
CSS (Cascading Style Sheets — каскадные таблицы стилей) — формальный язык описания внешнего вида документа, написанного с использованием языка разметки. Преимущественно используется как средство описания, оформления внешнего вида веб-страниц, написанных с помощью языков разметки HTML и XHTML, но может также применяться к любым XML-документам, например, к SVG или XUL.
В ранние годы (1990–1993) всемирной паутины HTML был довольно бедным языком. Он практически целиком состоял из структурных элементов, полезных для описания абзацев, гиперссылок, списков и заголовков. В нем не было ничего даже отдаленно напоминающего таблицы, фреймы или сложную разметку – того, что считается абсолютно необходимым для создания вебстраниц. HTML изначально задумывался, как структурный язык разметки, применяемый для описания различных частей документа. О том как должны отображаться эти части, говорилось совсем немного. Язык не затрагивал описание внешнего вида, он был лишь небольшой схемой разметки.
С нарастающей популярностью веба появлялась необходимость большего управления в оформлении представлений. Так появились атрибуты и теги, призванные менять внешний вид документа.
<font size="+3" face="Helvetica" color="red">Заголовок страницы</font>
При этом тег font
никак не влияет на структуру документа. Содержимое страниц стало превращаться в смесь полезных данных и “полезного” оформления.
<!--Пример кода без оформления-->
<body>
<h1>Основной заголовок</h1>
<p>Текст параграфа 1</p>
<h2>Подзаголовок 1</h2>
<p>Текст параграфа 2</p>
<h2>Подзаголовок 1</h2>
<p>Текст параграфа 3</p>
</body>
<!--Та же самая разметка, но уже с добавленными тегами оформления-->
<body bgcolor="#f1f1f1">
<h1 align="center"><font size="16px" color="red" face="Tahoma">Основной заголовок</font></h1>
<p><font size="8px" color="gray" face="Arial">Текст параграфа 1</font></p>
<h2><font size="10px" face="Tahoma">Подзаголовок 1</font></h2>
<p><font size="8px" color="gray" face="Arial">Текст параграфа 2</font></p>
<h2><font size="10px" face="Tahoma">Подзаголовок 2</font></h2>
<p><font size="8px" color="gray" face="Arial">Текст параграфа 3</font></p>
</body>
Конечно, проблема загрязнения HTML разметкой представления не осталась незамеченной консорциумом W3C (World Wide Web Consortium), который приступил к поиску решения. В 1995 году консорциум начал публикацию рабочего варианта стандарта, названного CSS. К 1996 году он получил статус рекомендации, такой же значимой, как и сам HTML. Причинами этого стали:
- Обеспечивают более богатое представление документа)
- Простота применения
- Возможность применения стилей к нескольким страницам
Но главной заслугой CSS стало разделение описания логической структуры от описания внешнего вида. Посмотрим на нашу разметку после добавления CSS.
<style>
body {
background: #f1f1f1;
}
h1 {
font-size: 34px;
color: red;
font-face: Tahoma;
text-align: center;
}
h2 {
font-size: 24px;
font-face: Tahoma;
}
p {
font-size: 18px;
color: gray;
font-face: Arial;
}
</style>
<!--Еще один вариант разметки, но уже с CSS-->
<body>
<h1>Основной заголовок</h1>
<p>Текст параграфа 1</p>
<h2>Подзаголовок 1</h2>
<p>Текст параграфа 2</p>
<h2>Подзаголовок 2</h2>
<p>Текст параграфа 3</p>
</body>
Селекторы ⇡
http://www.w3.org/TR/css3-selectors/
Одно из основных преимуществ CSS (особенно для разработчиков) – это возможность легко применять набор стилей (правило) ко всем однотипным элементам в документе. Отредактировав всего одну строку CSS, можно, например, изменить цвет всех заголовков в документе.
Чтобы лучше понять, как формируются правила, давайте разберем их структуру. Каждое правило имеет две основные части: селектор (selector) и блок объявлений (declaration block). Блок объявлений состоит из одного или более объявлений (declarations), а каждое объявление представляет собой сочетание свойства (property) и значения (value). Каждая таблица стилей образуется из наборов правил.
Селектор, расположенный в левой части правила, определяет, на какие элементы документа распространяется правило. На рисунке выбраны элементы h1
. Если бы селектором был p
, то выбирались бы все элементы p
(абзацы). В правой части правила находится блок объявлений, образованный одним или несколькими объявлениями. Каждое объявление представляет собой сочетание свойства CSS и значения этого свойства. На рисунке представлен блок, содержащий два объявления. Первое определяет, что согласно правилу цвет (color
) указанных элементов документа будет синим (blue
), а второе, что размер шрифта (font-size
) этих элементов будет 14px
. Таким образом, все элементы h1
(определенные селектором) этого документа будут выводиться синим текстом размером в 14px
.
В блок объявлений входит одно или несколько объявлений. Формат объявлений обычно такой: имя свойства, за которым следует двоеточие, затем значение и точка с запятой. После двоеточия и точки с запятой может быть произвольное количество пробелов (в частности, возможно отсутствие пробела). Практически во всех случаях значение – это или отдельное ключевое слово, или список из нескольких допустимых для данного свойства ключевых слов, разделенных пробелами. Если указать неверное свойство или значение, будет проигнорировано все объявление целиком. Поэтому следующие два объявления не будут выполнены:
font-saze: 12px; /* неизвестное значение (правильно font-size) */
color: ultraviolet; /* неизвестное значение (нет такого цвета) */
Бывают случаи, когда допускается указывать в качестве значения свойства более одного ключевого слова, ключевые слова обычно разделяются пробелами. Не все свойства могут принять несколько ключевых слов. Для примера рассмотрим свойство font
.
h1 { font: italic 40px Tahoma; } /* три значения для одного свойства */
Обратите внимание на пробел между значениями italic 40px и Tahoma
, каждое из которых является частью значения свойства font
(первое – начертание шрифта, второе – размер шрифта, а третье – фактическое имя шрифта). Благодаря пробелу браузер различает этот набор значений и применяет их. Точка с запятой указывает на завершение объявления.
Предположим, вы хотите, чтобы текст элементов h1
и абзацев был серого цвета. Проще всего это достигается посредством следующего объявления:
h1, p { color: gray; }
Поместив в левую часть разделенные запятой селекторы h1
и p
, вы определите правило, в котором находящийся в правой части стиль (color: gray;
) применится к элементам, обозначенным обоими селекторами. Запятая сообщает браузеру о том, что в правило включены два разных селектора. Если запятую опустить, правило приобретет совершенно другое значение (такой селектор станет селектором потомка)!
Универсальный селектор (universal selector) записывается символом звездочка (*). Этот селектор соответствует любому элементу почти так же, как подстановочный символ в маске имени файла. Например, чтобы сделать все элементы документа красными, можно написать:
* { color: red; }
Это описание эквивалентно групповому селектору, в котором перечислен каждый содержащийся в документе элемент (как-будто каждому элементу документа назначили значение red). Однако будьте внимательны: хотя универсальный селектор удобен, его не рекомендуют к применению.
Кроме простых селекторов элементов документа еще есть селекторы классов (class selectors) и селекторы идентификаторов (ID selectors), позволяющие назначать стили элементам независимо от их типа. Эти селекторы могут применяться самостоятельно или в сочетании с селекторами элементов. Однако работают они только в том случае, если документ размечен соответствующим образом, поэтому их применение подразумевает некоторое предварительное планирование.
Самый распространенный способ применения стилей без учета элементов состоит в том, чтобы обратиться к селектору класса. Однако сначала придется изменить разметку документа таким образом, чтобы обеспечить возможность работы этого селектора.
Чтобы связать стили селектора класса с элементом, необходимо присвоить соответствующее значение атрибуту class данного элемента. В CSS возможна очень краткая запись, в которой имени класса предшествует точка.
.warning { font-weight: bold; color: crimson; }
В примере правило применилось к двум элементам: первому абзацу и элементу span
во втором абзаце.
Ранее мы рассмотрели примеры, где значения атрибута class, состояли из одного слова. В HTML значением class может быть и разделенный пробелами список слов. Например, если вы хотите обозначить конкретный элемент и как важное сообщение, и как предупреждение, можно было бы написать:
.warning { font-weight: bold; color: crimson; }
Порядок слов на самом деле не имеет значения. Подошло бы и attention strong
.
Теперь, мы хотим, чтобы все элементы, у которых атрибут class имеет значение strong
, были выделены полужирным шрифтом, а те элементы, атрибут class которых имеет значение attention
, были выделены красным цветом, а элементы, имеющие оба значения, получили желтый фон. Это могло бы быть написано следующим образом:
.strong { font-weight: bold; }
.attention { color: crimson; }
.strong.attention { background: yellow; }
Объединяя два селектора класса, можно выбрать только те элементы, которые имеют оба имени класса, стоящие в любом порядке. Исходный код HTML содержит class="attention strong"
, но CSS селектор записан так: .strong.attention
. Несмотря на это правило применится к третьему абзацу.
В некотором смысле селекторы идентификаторов аналогичны селекторам классов, но есть два существенных отличия. Во-первых, перед селекторами идентификаторов вместо точки ставится «решетка» (#). Таким образом, возможно и такое правило:
#first { font-weight: bold; }
Оно устанавливает полужирный шрифт для любого элемента, у которого атрибут id
имеет значение first
.
Второе отличие – вместо значений атрибута class
в селекторах идентификаторов, используются значения атрибутов id
.
Назначать классы можно любому количеству элементов. С другой стороны, идентификаторы в HTML-документе используются только один раз. Поэтому если в документе есть элемент со значением атрибута id
, ни один другой элемент этого документа не может (на самом деле может и CSS будет работать нормально, но тогда идентификатор теряет свой основной смысл) иметь id
с таким же значением.
В отличие от селекторов класса, селекторы идентификаторов не могут объединяться, поскольку в атрибуты id
нельзя помещать разделенный пробелами список.
Еще одно отличие между именами class
и id
состоит в том, что идентификаторы имеют больший вес.
И в селекторах классов, и в селекторах идентификаторов речь на самом деле идет о выборе значений атрибутов.
Селектор .strong
применит правила к тем же элементам, что и селектор [class="strong"]
.
Для того чтобы выбрать элементы с определенным атрибутом независимо от значения этого атрибута, можно обратиться к простому селектору атрибутов. Например, чтобы выбрать все элементы, имеющие атрибут title
с любым значением, и сделать их текст красным, можно написать такое правило:
[title] { color: red; }
В дополнение к выбору элементов по атрибутам можно еще более сузить выбор, чтобы охватить только те элементы, атрибуты которых имеют определенное значение. Например, можно выделить полужирным шрифтом ссылки, указывающие на главную страницу сайта.
[href="https://ya.ru/"] { color: red; }
Поиск элементов по атрибуту не ограничивается точным совпадением. Мы можем написать селектор, который будет искать совпадение определенной части атрибута. Рассмотрим вариант, когда ссылка на страницу может быть как по протоколу http, так и https. В этом случае селектор на основании конкретного значения не найдет все ссылки на страницу, а вот селектор на основании частичного поиска справится с этой задачей:
[href*="ya.ru"] { color: red; text-decoration: none; }
Обратите внимание на наличие в селекторе звездочки(*). Это ключ для осуществления выбора на основании частичного совпадения. Если пропустить звездочку, то получится требование точного соответствия конкретному значению.
[href^="https"]
выбирает любой элемент, значение атрибута href которого начинается с "https".
[href$="ru"]
выбирает любой элемент, значение атрибута href которого заканчивается "ru".
[class~="strong"]
выбирает любой элемент, значение атрибута class которого содержит "strong" как отдельное слово.
http://www.w3.org/TR/selectors/#pseudo-classes
Псевдоклассы определяют динамическое состояние элементов, которое изменяется с помощью действий пользователя, а также положения в дереве документа.
Примером динамического псевдокласса состояния служит текстовая ссылка, которая меняет свой цвет в зависимости от того была ли ранее посещена страница, на которую указывает ссылка. При этом HTML никак не изменяется, потому что в нем нет никаких указателей на то, что по ссылке уже был переход.
:link
Ссылается на любую гиперссылку (т. е. имеющую атрибут href) и указывает на адрес, который не был посещен.
:visited
Ссылается на любую гиперссылку, указывающую на уже посещенный адрес.
a { color: red; }
a:visited { color: gray; }
CSS поддерживает псевдоклассы, которые могут изменять внешний вид документа в результате действий пользователя. Эти динамические псевдоклассы традиционно применяются для оформления ссылок и кнопок, но их возможности намного шире.
:focus
- соответствует элементу, которому в настоящий момент принадлежит фокус ввода, т.е. который готов принимать ввод с клавиатуры или быть активированным некоторым образом.
input:focus { background: blue; }
:hover
- соответствует элементу, над которым размещен указатель некоторого устройства, например ссылка, по которой проводят курсором мыши.
a:hover { color: red; }
:active
- соответствует элементу, который был активирован пользователем, например кнопка, по которой щелкает пользователь в течение того времени, когда удерживается кнопка мыши.
button:active { background: green; }
:target
- соответствует элементу, на который вы перешли по хеш-ссылке.
section:target { background: red; }
Для примера расмотрим меню, которое помогает переходить к нужному разделу на странице. Каждая ссылка содершит хеш, который является связывающим ключом с определенной секцией. По клику на ссылку соответствующая область будет выделена красным цветом.
:enabled
- соответствует элементам форм, которые являются доступным (не заблокированным) для изменения состояния. По умолчанию, все элементы форм являются доступными, если в коде HTML к ним не добавляется атрибут disabled
:disabled
- соответствует элементам форм, которые не являются доступным для изменения состояния
:checked
- соответствует элементам форм, таким как переключатели (checkbox) и флажки (radio), когда они находятся в положение «включено»
:indeterminate
- соответствует элементам форм, таким как переключатели (checkbox) и флажки (radio), когда они находятся в неопределенном состоянии
Структурные псевдоклассы позволяют выбирать элементы в зависимости от их положения в дереве элементов
Псевдокласс :first-child
применяется для выбора элементов, представляющих собой первые дочерние элементы других элементов. Для примера напишем селектор, который будет выбирать только первый элемент в списке.
li:first-child { color: green; }
Данный код можно прочитать справо-налево, как “выберем каждый первый элемент li
, который является дечерним по отношению к элементу ul
”
Самая распространенная ошибка – полагать, что такой селектор, как li:first-child
, выберет первый дочерний элемент элемента li
. На самом деле он выберет элемент li
, причем только в том случае, если этот элемент является первым дочерним элементом по отношению к своему родительскому элементу.
:root
- соответствует корневому элементу документа. В HTML этот селектор всегда соответствует элементу
:nth-child()
- соответствует элементам на основе заданной нумерации в дереве элементов
:nth-last-child()
- работает также, как и :nth-child()
, но в отличие от него отсчет ведется не от первого элемента, а от последнего
:nth-of-type()
- соответствует элементам указанного типа на основе нумерации в дереве элементов
:nth-last-of-type()
- работает также, как и :nth-of-type()
, но в отличие от него отсчет ведется не от первого элемента, а от последнего
:first-child
- соответствует первому дочернему элементу своего родителя
:last-child
- соответствует последнему дочернему элементу своего родителя
:first-of-type
- соответствует первому элементу указанного типа в списке дочерних элементов своего родителя
:last-of-type
- соответствует последнему элементу указанного типа в списке дочерних элементов своего родителя
:only-child
- соответствует дочернему элементу, только если он единственный у родителя
:only-of-type
- соответствует дочернему элементу указанного типа, только если он единственный у родителя
:empty
- соответствует пустому элементу (которые не содержат дочерних элементов, текста или пробелов)
Почти так же, как псевдоклассы назначают фантомные классы для ссылок, псевдоэлементы вводят фиктивные элементы в документ, чтобы достигнуть определенных эффектов.
Псевдоэлемент участвует в стилевом оформлении первой буквы блочного элемента.
p:first-letter { color: red; }
Согласно этому правилу первая буква каждого абзаца будет окрашена в красный цвет.
Аналогичным образом :first-line
может применяться для оформления первой строки текста элемента. Например, можно сделать первую строку каждого абзаца документа красной:
p:first-line { color: red; }
В css существует возможность добавлять контен до(:before
) и после(:after
) содержимого элементов. Для примера добавим строки “начало” и “конец” элементу body:
body:before { content: '=начало='; color: green; }
body:after { content: '=конец='; color: red; }
Обратите внимание на то, что псевдоэлементы before
и after
можно применять только к парным тегам.
Мощь CSS базируется на родительско-дочерних отношениях (parent–child relationship) элементов. HTML-документы строятся на основании иерархии элементов, которую можно показать в форме древовидного представления документа.
В этой иерархии каждый элемент тем или иным образом вписывается в общую структуру документа. Каждый элемент является или родительским (parent), или дочерним (child) элементом другого элемента, а зачастую выполняет обе эти роли. Элемент является родителем другого элемента, если в иерархии документа он находится прямо над этим элементом. Например, первый элемент p является родителем для элементов em и strong, тогда как strong – родитель элемента a, который в свою очередь является родителем другого элемента em. И наоборот, элемент является дочерним элементом другого элемента, если он находится прямо под этим элементом. Таким образом, элемент a – это дочерний элемент элемента strong, который в свою очередь является потомком элемента p, и т. д.
Термины родительский и дочерний элементы – это частные случаи терминов предок (ancestor) и потомок (descendant). Между ними существует разница: если в представлении в виде древовидного списка элемент находится ровно на один уровень выше другого, между ними существуют родительско-дочерние отношения. Если путь от одного элемента к другому пересекает два или более уровней, между элементами существуют отношения предок-потомок, но не родительско-дочерние. (Конечно, дочерний элемент также является потомком, а родитель – предком.) На рисунке первый элемент ul – это родитель двух элементов li, но первый ul также является предком всех элементов, происходящих от его элемента li, вплоть до самых глубоко вложенных элементов li. Также на рисунке показан элемент a, который является дочерним по отношению к strong, но еще и потомком абзаца, элементов body и html. Элемент body – предок всего, что броузер будет отображать по умолчанию, а элемент html – предок всего документа. Поэтому элемент html также называют корневым элементом (root element).
Определение селекторов потомков – это создание правил, действующих лишь в рамках заданной структуры. Например, требуется задать стили только для тех элементов a, которые происходят от элемента nav. Для этого можно объявить правила, которые соответствуют только элементам а, находящимся внутри элементов nav.
nav a { color: red; text-decoration: none; }
Это правило сделает цвет ссылок, которые являются потомками элемента nav, красным. Цвет других элементов a, например, находящихся в абзаце или блоке, не будет выбран этим правилом.
В селекторе потомков часть правила, соответствующая селектору, состоит из двух или более разделенных пробелами селекторов. Пробел между селекторами – это пример комбинатора (combinator). Каждый комбинатор - пробел, если читать его справа налево, он может быть истолкован как «находящийся в», «который представляет собой часть» или «являющийся потомком». Таким образом, “nav a” можно прочитать как: «любой элемент а, который является потомком элемента nav». (Если прочитать селектор слева направо, может получиться примерно следующее: «для любого “nav”, содержащего “а”, к “а” будут применены следующие стили».) Конечно, два селектора не предел. Например:
article p a abbr { color: red; text-decoration: none; }
В некоторых случаях не требуется выбирать любой элемент-потомок. Напротив, необходимо сузить диапазон выбора до дочернего элемента другого элемента. Предположим, надо выбрать элемент strong, только если он является дочерним элементом (а не просто потомком) элемента h1. Для этого используется символ-комбинатор селектора дочерних элементов, которым является символ «больше» (>):
h1 > strong { color: red; }
Это правило сделает красным элемент strong для первого из следующих далее h1 и не сделает для второго:
<h1>Это <strong>очень</strong> важно.</h1>
<h1>Это <em>действительно <strong>очень</strong></em> важно.</h1>
Прочитанный справа налево селектор h1 > strong
переводится как «выбираем любой элемент strong, являющийся дочерним элементом h1
». Комбинатор селектора дочерних элементов может быть окружен пробелами. Таким образом, селекторы: h1>strong
и h1 > strong
эквивалентны.
На этом фрагменте дерева можно без труда выделить родительско-дочерние отношения. Например, элемент a
– родитель элемента strong
, он же и дочерний элемент элемента p
. Можно было бы сопоставить элементы этого фрагмента с селекторами p > a
и a > strong
, но не с селектором p > strong
, поскольку strong
является потомком p
, а не дочерним элементом.
Рассмотрим еще один пример. Предположим у нас есть блок комментариев и нам необходимо сделать внутри внутри каждого комментария красными только те ссылки, которые являются прямыми потомками.
article > a { color: red; }
Чтобы выбрать элемент, который расположен сразу за другим элементом и имеет того же родителя, применяется комбинатор селектора соседних элементов (adjacent-sibling combinator), представляемый в виде знака плюс (+). Как и комбинатор селектора дочерних элементов, этот символ может быть окружен пробелами.
Чтобы удалить верхний отступ абзаца, следующего за элементом h1
, запишем:
h1 + p { margin-top: 0; } /* любой абзац, расположенный за элементом h1, имеющий общих родителей с элементом p */
Этот селектор означает следующее: «выбираем любой абзац, расположенный за элементом h1
, имеющий общих родителей с элементом p
». Наглядно представить себе, как работает этот селектор, проще всего, еще раз рассмотрев фрагмент дерева документа.
В этом фрагменте от элемента div происходит пара списков, один нумерованный, а другой нет, каждый из которых содержит по три элемента списка. Списки представляют собой сестринские элементы, и сами элементы списков тоже сестринские элементы. Однако элементы первого списка не являются сестринскими для элементов второго списка, поскольку их родительские элементы разные. В лучшем случае они являются кузинами.
li + li { font-weight: bold; } /* выбрать li, перед которым есть li */
ol + ul { background: yellow; } /* выбрать ol, перед которым есть ul */
Из двух сестринских элементов одним комбинатором выбирается только второй элемент. Поэтому если вы записываете:
li + li { font-weight:bold; }
Полужирным шрифтом будут выделены только второй и третий элементы каждого списка. Первые элементы списков останутся нетронутыми.
Для обеспечения правильной работы CSS требует, чтобы два элемента были приведены в «исходном порядке». В нашем примере за элементом ol
следует элемент ul
. Это позволяет выбрать второй элемент с помощью селектора ol + ul
, но первый элемент по средством аналогичного синтаксиса выбрать не удастся.
Рассмотрим другой пример. Допустим нам необходимо разделить комментарии пользователей красной линией, при этом необходимо выделить весь блок комментариев черными линиями (перед первым и после последнего комментария).
h3 + article { border-top: 2px solid black; }
/* добавляем черную 2-х пиксельную линию для article, перед которым есть h3 */
article + article { border-top: 1px solid red; }
/* добавляем красную однописельную линию для article, перед которым есть article */
article + footer { border-top: 2px solid black; }
/* добавляем черную 2-х пиксельную линию для footer, перед которым есть article */
Чтобы выбрать все элементы определенного типа, расположенные на одном уровне с другим элементом и имеющие того же родителя, применяется комбинатор селектора сестринских элементов (General sibling combinator), представляемый в виде знака тильда (~).
Селектор выбора сестринских элементов очень похож на селектор выбора соседних элементов с той лишь разницей, что селектор выбора сестринских элементов выбирает не соседний элемент, а все последующие.
Для примера рассмотрим фому регистрации, в которой текстовые поля будут показаны только после перевода checkbox
в состояние checked
.
[type="text"] { visibility: hidden;}
/* по умолчанию все текстовые поля скрыты*/
[type="checkbox"]:checked ~ [type="text"] { visibility: visible; }
/* показываем все текстовые поля, которые расположены после checkbox и на одном уровне с ним, когда checkbox в состоянии checked */
Псевдокласс :not
соответствует элементам, которые не содержат указанный селектор. Допустим у нас есть таблица, мы хотим задать зеленый фон ячейкам, которые содержат внутри текст и красный фон ячейкам, которые пустые.
td:empty { background: red; } /* красный фон для пустых ячеек */
td:not(:empty) { background: green; } /* зеленый фон для ячеек, которые не являются пустыми */
Специфичность ⇡
Итак, мы уже знаем, что существует множество способов выбора необходимых элементов. Фактически один и тот же элемент может быть выбран двумя и более правилами, каждое из которых имеет собственный селектор.
h1 { color: red; }
body h1 { color: green; }
Очевидно, что применено будет только одно из двух правил каждой пары, поскольку сопоставляемый элемент может быть только одного цвета. А как узнать, какое из правил применится?
Ответ кроется в специфичности (specificity) каждого селектора. Для каждого правила браузер вычисляет специфичность селектора (его вес) и прикрепляет ее к каждому объявлению правила. Если элемент имеет несколько конфликтующих объявлений одного свойства, выигрывает то, которое имеет наибольшую специфичность.
Специфичность селектора определяется компонентами самого селектора. Значение специфичности состоит из четырех частей: 0, 0, 0, 0. Реальная специфичность селектора определяется следующим образом:
- Для каждого указанного в селекторе значения идентификатора к специфичности добавляется 0, 1, 0, 0.
- Для каждого указанного в селекторе имени класса, псевдокласса или атрибута к специфичности добавляется 0, 0, 1, 0.
- Для каждого заданного в селекторе элемента и псевдоэлемента к специфичности добавляется 0, 0, 0, 1.
- Универсальный селектор не учитывается
Примеры:
h1 { color: red; } /* специфичность = 0, 0, 0, 1 */
p em { color: purple; } /* специфичность = 0, 0, 0, 2 */
.grape { color: purple; } /* специфичность = 0, 0, 1, 0 */
* .bright { color: yellow; } /* специфичность = 0, 0, 1, 0 */
p.bright em.dark { color: maroon; } /* специфичность = 0, 0, 2, 2 */
#id216 { color: blue; } /* специфичность = 0, 1, 0, 0 */
div#sidebar [href] { color: silver; } /* специфичность = 0, 1, 1, 1 */
* { color: yellow; } /* специфичность = 0, 0, 0, 0 */
h1 {color: red;} /* 0, 0, 0, 1 */
body h1 {color: green;} /* 0, 0, 0, 2 (победитель) */
Вес значения растет слева направо. Специфичность 1, 0, 0, 0 возьмет верх над любой специфичностью, которая начинается с 0, независимо от того, какими будут остальные числа. Таким образом, 0, 1, 0, 1 выигрывает у 0, 0, 1, 7, потому что 1, стоящая на втором месте первого значения, побеждает 0 на этом месте во втором значении.
h1, h2.section { color: silver; background: black; }
Чтобы определить специфичность, браузер пользователя должен рассматривать правило так, как будто бы оно разделено на отдельные «разгруппированные»
h1 { color: silver; background: black; } /* 0, 0, 0, 1 */
h2.section { color: silver; background: black; } /* 0, 0, 1, 1 */
Важно понимать разницу в специфичности селектора идентификатора (ID selector) и селектора атрибутов (attribute selector), в котором указан атрибут id.
#uniq { color: green; } /* 0, 1, 0, 0 */
[id='uniq'] { color: red; } /* 0, 0, 1, 0 */
Все рассмотренные до сих пор значения специфичности начинались с нуля. Дело в том, что этот первый нуль зарезервирован для встроенных объявлений стилей, специфичность которых превосходит специфичность всех остальных объявлений. Рассмотрим следующее правило и фрагмент разметки:
<style>
#uniq { color: green; } /* 0, 0, 0, 1 */
[id='uniq'] { color: red; } /* 0, 1, 0, 0 */
</style>
<h1 id="uniq" style="color: blue;">CSS</h1> /* 1, 0, 0, 0 */
Исходя из того, что это правило применяется к элементу h1
, можно ожидать, что текст h1
будет синим. Так и происходит, объясняется это тем, что специфичность данного объявления равна 1, 0, 0, 0. Это значит, что даже элементы с атрибутами id
, которые сопоставляются с правилом, подчиняются встроенным в тег стилям.
Важность ⇡
Иногда важность объявления настолько велика, что перевешивает все остальные факторы. В CSS их называют важными объявлениями (important declarations).
Важность добавляется путем введения в объявление ключевого слова !important
прямо перед завершающей точкой с запятой:
#uniq {
color: green !important;
font-size: 20px;
}
Здесь значение цвета #333
отмечено как !important
, тогда как размер шрифта – нет. Если необходимо сделать важными оба объявления, каждому из них понадобится собственный маркер !important
:
#uniq {
color: green !important;
font-size: 20px !important;
}
Ключевое слово !important
всегда располагается в конце объявления, прямо перед точкой с запятой.
Объявления, отмеченные как !important
, не имеют особого значения специфичности, они рассматриваются отдельно от остальных. Фактически все объявления !important
группируются вместе, и тогда уже их конфликты специфичностей разрешаются относительно друг друга. Аналогично группируются все остальные объявления, и конфликты свойств разрешаются с помощью специфичностей. В любом случае, когда имеет место конфликт важного и неважного объявления, всегда побеждает важное
Наследование ⇡
Наследование – это механизм, с помощью которого стили применяются не только к указанным элементам, но также к их потомкам. Например, если цвет применен к элементу p
, то этот цвет будет применен ко всему тексту в p
и даже к тому, который заключен в дочерние элементы этого p
.
<style>
p { color: green; }
</style>
<p><strong>Каскадные таблицы стилей</strong> – мощный механизм …>
И обычный текст p
, и текст strong
окрашены в зеленый цвет, потому что элемент strong
наследует значение color
. Если бы значения свойств не наследовались элементами-потомками, текст strong
был бы черным, а не зеленым, и пришлось бы окрашивать этот элемент отдельно.
Лучше всего принцип работы наследования иллюстрирует древовидное представление документа. На рисунке показана древовидная схема простого документа, содержащего два списка – ненумерованный и нумерованный. Когда к элементу ul
применяется объявление color: green;
он принимает это объявление. Затем это значение передается вниз по дереву элементов-потомков до тех пор, пока не останется потомков, которые могли бы наследовать это значение. Значения никогда не передаются вверх по иерархии, т. е. элемент никогда не передает значение своим предкам
Но не все свойства наследуются. Это обусловлено тем, что наследование таких свойст (border, padding и д.р.) может создать много проблем.
Список наиболее часто используемых свойст, которые наследуются:
- color
- cursor
- direction
- empty-cells
- font-family
- font-size
- font-weight
- font-style
- font-variant
- font
- letter-spacing
- list-style-type
- list-style-position
- list-style-image
- list-style
- line-height
- quotes
- text-align
- text-indent
- text-transform
- visibility
- white-space
- word-spacing
Более подробный список для второй версии CSS можно посмотреть здесь
С точки зрения специфичности унаследованные значения вообще не имеют веса, даже нулевого. Рассмотрим следующие правила и фрагмент разметки:
<style>
* { color: gray; }
p { color: green; }
</style>
<p><strong>Каскадные таблицы стилей</strong> (CSS – Cascading Style Sheets) …>
Поскольку универсальный селектор применяется ко всем элементам и имеет нулевую специфичность, заданный в нем серый цвет для элемента strong
одерживает верх над унаследованным значением green
, которое вообще не имеет никакой специфичности. Следовательно, цвет элемента strong
будет серым, а не зеленым.
Каскад ⇡
Часто на практике можно можно встретить ситуацию применения правил с одинаковыми свойствами и специфичностью, но с разными значениями свойств.
h1 { color: red; }
h1 { color: blue; }
Какое из них победит? Специфичность обоих равна 0, 0, 0, 1,
у них равные шансы, и они оба должны быть применены. Для решения таких ситуаций существует каскад. CSS основывается на методе каскадирования стилей, реализация которого стала возможной благодаря сочетанию наследования и специфичности. Правила каскадирования очень просты:
-
Найти все правила, содержащие селектор, сопоставляемый с данным элементом.
-
Провести сортировку согласно явной приоритетности всех применяемых к элементу объявлений. Правилам, отмеченным как !important, присваивается более высокий приоритет, чем остальным. Так же все применяемые к данному элементу объявления сортируются согласно их источнику. Существует три возможных источника правил: автор, читатель и браузер. В общем случае стили автора приоритетней стилей читателя. Но стили читателя, отмеченные как
!important
, сильнее, чем все остальные стили, включая и те стили автора, которые отмечены как!important
. И стили автора, и стили читателя замещают применяемые по умолчанию стили браузера. -
Провести сортировку всех объявлений, применяемых к элементу, согласно их специфичности. Элементы с более высокой специфичностью имеют больший приоритет по сравнению с теми, специфичность которых ниже.
-
Провести сортировку всех объявлений, применяемых к элементу, в соответствии с очередностью расположения. Чем позже объявление появляется в таблице стилей или документе, тем больший приоритет ему присваивается. Считается, что объявления, находящиеся в импортированных таблицах стилей, располагаются перед всеми объявлениями импортировавшей их таблицы стилей.
Согласно второму правилу, если к элементу применяются два правила и одно из них отмечено как !important
, то оно побеждает:
<style>
p { color: gray !important; }
</style>
<p style="color: green"><strong>Каскадные таблицы стилей</strong> (CSS – Cascading Style Sheets) …>
Несмотря на то что цвет задан в атрибуте style
абзаца, побеждает правило с пометкой !important
, и текст абзаца становится серым. Этот серый цвет также наследуется элементом strong
.
Более того, учитывается источник правила. Если с элементом сопоставляются стили с обычной приоритетностью из таблицы стилей автора и таблицы стилей читателя, то применяются стили автора. Предположим, что следующие стили происходят из указанных источников:
p strong { color: black; } /* таблица стилей автора */
p strong { color: yellow; } /* таблица стилей читателя */
В данном случае выделенный текст параграфа закрашивается черным цветом, а не желтым, потому что стили автора с обычной приоритетностью побеждают обладающие обычным приоритетом стили читателя.
Однако если оба правила отмечены как !important, ситуация меняется:
p strong { color: black !important; } /* таблица стилей автора */
p strong { color: yellow !important; } /* таблица стилей читателя */
Теперь выделенный текст параграфа будет желтым, а не черным. Так сложилось, что применяемые по умолчанию стили браузера, которые обычно отражают предпочтения пользователя, учитываются именно так. Применяемые по умолчанию объявления стилей вообще относятся к категории правил, обладающей наименьшим влиянием. Поэтому если заданное автором правило применяется к тегам a
(например, объявляет, что они будут белыми), то оно замещает стандартные настройки браузера.
С точки зрения приоритетности объявлений выделены пять уровней. В порядке уменьшения приоритетности это:
- Важные объявления читателя.
- Важные объявления автора.
- Обычные объявления автора.
- Обычные объявления читателя.
- Объявления браузера.
Согласно третьему правилу, если к элементу применяются конфликтующие объявления и все они имеют одинаковую приоритетность, они должны сортироваться в соответствии со специфичностью. Побеждает объявление, обладающее наибольшей специфичностью.
<style>
.content { color: green; }
p { color: gray; }
</style>
<p class="content"><strong>Каскадные таблицы стилей</strong> (CSS – Cascading Style Sheets) ...?>
Исходя из приведенных правил текст параграфа будет окрашен в зеленый цвет, потому что специфичность .content (0, 1, 0, 0)
превышает специфичность p (0, 0, 0, 1)
, даже несмотря на то, что последнее правило расположено в таблице стилей позже.
И наконец, согласно четвертому правилу, если два правила имеют совершенно одинаковую приоритетность, источник и специфичность, тогда побеждает то, которое расположено в таблице стилей ниже. Вернемся к нашему предыдущему примеру, в котором мы нашли следующие два правила таблицы стилей документа:
h1 { color: red; }
h1 { color: blue; }
Значение color
для всех элементов h1
документа будет blue
, а не red
, поскольку именно это правило стоит в таблице стилей ниже.
Значения и единицы измерения ⇡
demo Единицы измерения (units), применяются во многих свойствах для задания цвета, расстояний и размеров. Без единиц измерения нельзя объявить о том, что текст абзаца должен быть нужного размера, или что вокруг изображения должно быть пустое пространство в 10 пикселей.
В CSS существует два типа чисел: целые (integer) и вещественные (real). Эти типы чисел в большинстве случае в служат базой для всех остальных типов значений
p {
font-size: 20px;
line-height: 1.5;
}
Процентное значение (percentage value) – это вычисляемое вещественное число, за которым следует знак процента (%). Процентные значения практически всегда выражены относительно другого значения, которым может быть все что угодно, включая значение другого свойства того же элемента, значение, унаследованное от родительского элемента, или значение элемента предка. Любое свойство, принимающее значения, задаваемые в процентах, определяет свои ограничения на допустимый диапазон процентных значений и точность представления относительных процентных значений. Для примера рассмотрим следующее правило:
p {
font-size: 20px;
width: 50%;
line-height: 150%;
}
Ширина p будет равна половине ширины его родителя (width: 50%
), потому что процентное значение ширины в данном случае расчитывается от значения ширины родителя. В тоже время значение line-height
, заданное как 150%
будет равно 30px
, так как расчитывается от своего собственного значения элемента font-size
, которое равно 20px
.
http://www.w3.org/TR/css3-color/
В CSS цвет можно задавать различными способами
Самый интуитивно понятный способ задать значение цвета, это использовать ключевое слово.
h1 { color: fuchsia; }
p { background: yellow; }
demo
Далее представлен список некоторых возможных цветов: aqua
, fuchsia
, lime
, olive
, red
, white
, black
, gray
, maroon
, orange
, silver
, yellow
, blue
, green
, navy
, purple
.
Компьютеры создают цвета путем комбинирования различных уровней красного, зеленого и синего. Такую комбинацию называют цветовой моделью RGB. В этих точках яркости каждого из лучей комбинируются, образуя все цвета, которые вы видите. Существует несколько способов задания цвета, используя цветовою модель RGB.
Существует два варианта задания цвета, основанных на функциональном формате записи RGB (functional RGB notation). Обобщенный синтаксис кодировки цвета – rgb(color)
, где color представляет собой комбинацию трех процентных значений или целых чисел. Допустимый диапазон процентных значений – от 0% до 100%, а диапазон целых значений – от 0 до 255. Следовательно, код, задающий белый и черный цвета с помощью процентных значений, будет таким: rgb(100%, 100%, 100%)
rgb(0%, 0%, 0%)
. А вот те же цвета, представленные записью из целых чисел (integertriplet notation): rgb(255, 255, 255)
rgb(0, 0, 0)
p { color: rgb( 40%, 40%, 40% ); }
p { color: rgb( 102, 102, 102 ); }
Запись в виде целых удобнее для тех, кто работает с такими программами, как Photoshop
Модель RGBA - вариант модели RGB, но с дополнительным параметром (альфа канал), который задает прозрачность цвета.
p { color: rgba( 40%, 40%, 40%, 0.5 ); }
p { color: rgba( 102, 102, 102, 0.8 ); }
CSS позволяет определять цвет с помощью шестнадцатеричной записи. При такой форме записи цвет задается посредством объединения трех шестнадцатеричных чисел в диапазоне от 00
до FF
. Обобщенный синтаксис для этой формы записи – #RRGGBB
. Обратите внимание, что здесь между числами нет ни пробелов, ни запятых, ни каких-либо других разделителей.
.red { color: #ff0000; }
.orange { color: #eea837; }
Для шестнадцатеричных чисел, составленных из трех согласованных пар символов, CSS допускает более короткую запись. Обобщенный синтаксис для этой формы записи – #RGB
.red { color: #f00; } /* #f00 = #ff0000 */
.gray { color: #888; } /* #888 = #888888 */
Для измерения длины существует множество способов.
Единицы измерения длины могут быть представлены как положительные или отрицательные числа (хотя некоторые свойства будут принимать только положительные значения), за которыми следует обозначение единиц измерения. Числа могут быть и вещественными, т. е. содержать дробную часть, например 10.5 или 4.561. Все значения длины сопровождаются двухбуквенной аббревиатурой, представляющей единицы измерения, например in
(дюймы) или pt
(пункты). Единственное исключение из этого правила – нулевая длина(0), для которой не надо указывать единицы измерения.
Различают два типа единиц измерения длины: абсолютные единицы измерения (absolute length units) и относительные (relative length units)
Начнем с абсолютных единиц измерения, потому что они проще для понимания, несмотря на тот факт, что они практически не применяются в разработке веб-страниц.
- Миллиметры (mm)
- Сантиметры (cm) - 0,0394 дюйма
- Дюймы (in) - 2,54 сантиметра
- Пункты (pt) - это стандартная типографская единица измерения, которая десятилетиями используется в принтерах, наборных машинах и в программах обработки текстов. Традиционно дюйму соответствуют 72 пункта
- Пики (pc) еще один типографский термин. Пика эквивалентна12 пунктам, т. е. в дюйме 6 пик. А одна пика равна одной шестой доле дюйма
Абсолютные единицы измерения намного удобнее при определении таблиц стилей для печатных документов, где измерения в дюймах, пунктах и пиках – обычное дело, а вот для веб разрабки они не подходят.
Относительные единицы измерения получили такое название потому, что они измеряются относительно других единиц измерения. Измеряемое ими фактическое (или абсолютное) расстояние может меняться под действием внешних факторов, таких как разрешение экрана, ширина области просмотра, предпочтительные настройки пользователя и массы других параметров. Кроме того, для некоторых относительных единиц измерения их размер практически всегда измеряется относительно использующего их элемента и соответственно будет меняться от элемента к элементу
Пиксель – это точка на экране. Может показаться, что это самый простой и понятный способ задать значение css-свойству, потому что нет необходимости производить расчеты относильно другого значения. Но почему тогда пискель относительная еденица измерения? Дело в том, что размер пикселя зависит от разрешения устройства и его технических характеристик.
div {
border: 2px solid red;
width: 100px;
height: 50px;
}
В CSS один «em» – это значение свойства font-size
заданного шрифта. Если для элемента font-size
равен 14 пикселам, тогда для него же 1em
равен 14 пикселам. Это значение может меняться от элемента к элементу. Например, возьмем h1
, размер шрифта которого составляет 32 пиксела, элемент h2
, размер шрифта которого составляет 24 пикселов, и абзац со шрифтом в 18 пикселов. Если задать левый отступ в 1em
для всех трех элементов, то отступ слева для них будет 32, 24 и 18 пикселов соответственно.
h1, h2, h3 {
padding-left: 1em;
}
Кроме того значение em меняется в зависимости от размера шрифта родительского элемента. Так если элементу задать font-size
равный 20px
, то при задании дочернему элементу значения шрифта 1.5em
по факту на экране мы увидим текст со значением в 30px
(20 * 1.5). Но если у дочернего элемента будут свои дочернии элементы, для них значение 1em
будет равно уже 30px
.
<div>
<p><strong>Каскадные таблицы стилей (CSS – Cascading Style Sheets)</strong> – мощный механизм управления представлен ием отдельных документов или их наборов</p>
</div>
<style>
div { font-size: 20px; }
p { font-size: 1.5em; } /* 30px (20 * 1.5) */
strong { font-size: 1.2em; } /* 36px (30 * 1.2) */
</style>
Величина ex опирается на высоту буквы x нижнего регистра выбранного шрифта. Поэтому, если в двух абзацах размер текста составляет 20px
пункта, но для каждого абзаца выбран свой шрифт, то значение ex для каждого из них может быть различным. Дело в том, что высота буквы «x» в разных шрифтах разная. В примере продемонстрировано, как меняется ширина елемента заданного в ex в зависимости от шрифта.
url - это формат обращения к нужному элементу (картинке, css-файлу). Может быть как относительным, так и абсолютным.
.yandex { background: url("//yastatic.net/morda-logo/i/bender/logo.svg"); }
Очень распространенный пример – ключевое слово none, отличающееся от 0 (нуля). Так, чтобы удалить подчеркивание ссылок в HTML-документе, можно написать:
a { text-decoration: none; }
Аналогично, если бы потребовалось подчеркнуть ссылки, можно было бы указать ключевое слово underline
.
Если свойство допускает применение ключевых слов, то его ключевые слова определены только для этого свойства. Если одно и то же слово задано как ключевое для двух свойств, то действие ключевого слова для одного свойства никак не будет связано с его действием в рамках другого свойства. В качестве примера возьмем слово normal
. Определенное для свойства letter-spacing
, оно означает нечто совершенно отличное от того, что задает normal
для свойства font-style
.
Добавление CSS на страницу ⇡
CSS можно добавить на страницу разными способами
<html>
<head>
<link rel="stylesheet" type="text/css" href="https://goo.gl/vyqNwv">
<style type="text/css">
@import url(https://goo.gl/Y32anZ);
h1 { font-size: 20px; }
body { background: yellow; }
</style>
</head>
<body>
<h1 style="text-align: center">CSS</h1>
<p>Каскадные таблицы стилей (CSS – Cascading Style Sheets) – мощный механизм управления представлением отдельных документов или их наборов.</p>
</body>
</html>
<link rel="stylesheet" type="text/css" href="https://goo.gl/vyqNwv">
При использовании связанных стилей описание селекторов и их значений располагается в отдельном файле, а для связывания документа с этим файлом применяется тег link
. Данный тег помещается в контейнер head
.
Значение href задаёт путь к CSS-файлу, он может быть задан как относительно, так и абсолютно. Таким образом можно подключать таблицу стилей, которая находится на другом сайте.
Файл со стилем не хранит никакие данные, кроме синтаксиса CSS. В свою очередь и HTML-документ содержит только ссылку на файл со стилем, т. е. таким способом в полной мере реализуется принцип разделения кода и оформления сайта. Поэтому использование связанных стилей является наиболее универсальным и удобным методом добавления стиля на сайт.
<style type="text/css">
h1 { font-size: 20px; }
body { background: yellow;}
</style>
При использовании глобальных стилей свойства CSS описываются в самом документе и располагаются в заголовке веб-страницы. По своей гибкости и возможностям этот способ добавления стиля уступает предыдущему, но также позволяет хранить стили в одном месте, в данном случае прямо на той же странице с помощью контейнера style
. В нем будут содержаться применяемые к документу стили, но он также может включать ссылки на внешние таблицы стилей с помощью директивы @import
@import url(https://goo.gl/Y32anZ);
Так же как и link
, @import
может указывать браузеру на необходимость загрузки внешней таблицы стилей и использования ее стилей при формировании представления HTML документа. Единственное основное отличие заключается в синтаксисе и размещении команды. Директива @import
может находиться только в контейнере style
. Она должна располагаться перед всеми остальными правилами CSS, иначе не будет работать.
В документе может быть несколько директив выражения @import
, как и тегов link
.
<h1 style="text-align: center">CSS</h1>
Внутренний или встроенный стиль является по существу расширением для одиночного тега используемого на текущей странице. Для определения стиля используется атрибут style
, а его значением выступает набор стилевых правил.
Внутренние стили рекомендуется применять на сайте ограниченно или вообще отказаться от их использования. Дело в том, что добавление таких стилей может увеличить общий объём файлов, что ведет к повышению времени их загрузки в браузере, и усложнению редактирования документов для разработчиков.
Типы устройств ⇡
Одной особенностью CSS является возможность подключения тех или иных стилей в зависимости от типа устройства. Благодаря чему можно сделать отдельные таблицы стилей для мониторов, принтеров, мобильных телефонов, звуковых или тактильных браузеров и т.д.
Обозначение | Типы устройств |
---|---|
all | Таблица стилей используется для всех устройст |
aural | Для речевых синтезаторов |
braille | Устройства для слепых людей |
embossed | Страничные принтеры для слепых людей |
handheld | Для устройств с небольшими экранами (мобильные телефоны, карманные компьютеры и т.д.) |
Используется при выводе документа на печать | |
projection | Для проектора |
screen | Экран компьютерного монитора |
tty | Устройства, использующие символьную сетку экрана фиксированного шага, например телетайп |
tv | Для экранов подобно телевизионным (низкое разрешение, ограниченная цветопередача, отсутствует прокрутка и т.д.) |
Отдельные таблицы стилей могут быть удобны по многим причинам. Например, при выводе на принтер можно убрать меню сайта или рекламные блоки. Также можно изменить шрифт, так как из-за особенностей зрения человека, текст написанный шрифтами без засечек (Arial, Verdana и т.д.) гораздо удобней читать с монитора компьютера, а вот с засечками (Times, Times New Roman и т.д.) наоборот, с бумаги.
Есть несколько способов подключения стилей для конкретных устройств. Рассмотрим один из них.
Выбор устройств с помощью тегов link
. Данный вид подключения основан на добавлении атрибуда media
с указанием типа устройства.
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" type="text/css" href="all.css">
<link rel="stylesheet" type="text/css" href="tv.css" media="tv">
<link rel="stylesheet" type="text/css" href="print.css" media="print">
</head>
<body>
<p>Текст параграфа.</p>
</body>
</html>
В этом примере стили из файла all.css
будут использоваться на всех устройствах.
Стили из файла tv.css
будут применяться при просмотре страницы на телевизорах, а стили из файла print.css
при печати документа.
Другие способы подключения можно посомтреть тут и тут
Ссылки ⇡
- CSS от W3C http://www.w3.org/TR/CSS/
- Селекторы http://www.w3.org/TR/css3-selectors/
- Значения и единицы измерения http://www.w3.org/TR/css3-values/
- Цвета http://www.w3.org/TR/css3-color/
Книги ⇡
- CSS Pocket Reference (Eric Meyer) http://goo.gl/gnPYYa
- The CSS Anthology: 101 Essential Tips, Tricks & Hacks (Rachel Andrew http://goo.gl/ILcxLd
- Stunning CSS3: A project-based guide to the latest in CSS (Zoe Mickley Gillenwater) http://goo.gl/Xr0Mkf