Идеально! Как создать и переделать свой сайт. Правильный подход и передовые техники разработки

Стокс Элиот Джей

Веру Ли

Эндрю Рэйчел

Фадеев Дмитрий

Балкан Арэл

Хейлманн Кристиан

Боуг Пол

Эдвардс Марк

Уолтер Аарон

Шварц Бен

Кларк Энди

Хей Стивен

Стори Дэвид

Меняем стиль, переписываем код и преображаем сайт с помощью CSS3

Автор: Дэвид Стори, Ли Веру

Рецензент: Тэб Аткинс, мл.

 

 

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

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

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

 

Сайты не должны выглядеть одинаково во всех браузерах

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

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

 

Система нейтрализации ошибок

Использование изящной обработки ошибок таблицами CSS и каскадность – самый несложный способ обеспечить систему восстановления. Основная идея проста: в CSS, браузеры игнорируют то, чего они не понимают. Так, если они не понимают свойство или значение, они проигнорируют все описание. Если они не понимают селектор, они проигнорируют целое правило. Если они не понимают правило, начинающееся со знака @, они проигнорирую все внутри него.

Посмотрите на этот простой CSS-код:

a {

color: black;

color: super-cool-new-css-color;

super-cool-new-css-property: awesomesauce;

}

a: hawt-new-pseudoclass(awesomeness) {

color: hotpink;

}

В браузерах, которые поддерживают: hawt-new-pseudoclass, цвет ссылок, которые размечены им, будет hotpink. Во всех остальных случаях цвет определяется первым правилом. В таких случаях, если super-cool-new-css-color – поддерживаемый браузером цвет, то ссылки будут такого цвета. В противном случае они будут черными. А если поддерживается свойство super-cool-new-css-property, цвет будет применяться ко всем ссылкам; в противном случае он будет проигнорирован и не вызовет проблемы. Иногда (правда, редко), этот метод не помогает. Например, когда не поддерживаются новые приемы верстки, вам нужно задать полностью другой макет, используя множество свойств, которые не будут перезаписаны на новые. В таких случаях поможет определение поддержки фич.

Moderniz от Фарука Атеса и Пола Айриша считается одной из наиболее используемых библиотеки поддержки фич. Она добавляет классы к корневым элементам, которые вы потом сможете использовать в своей CSS-ветке соответственно:

no-flexbox section {

/* разметка макета со старыми стилями */

}

flexbox section {

/* разметка с поддержкой новых клевых штук */

}

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

 

Как читать этот раздел

Многие свойства библиотеки CSS3, описанные в этом разделе все еще используются с префиксами браузеров. Как только свойство превращается в стандарт и широко поддерживается браузерами, префиксы могут быть «выброшены». Для того чтобы воспользоваться ими сегодня, вам нужно приписывать к началу свойcтва один или несколько префиксов, которые даны ниже:

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

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

Префиксы производителя часто необходимы. Присутствие в вашей таблице стилей всех префиксов -o-, -ms-, -moz-and-webkit – наихудший сценарий. Не всем свойствам они нужны. Вы можете посмотреть, какие префиксы еще нужны, в справочных таблицах по поддержке браузеров.

На ресурсах When Can I Use, HTML5 Please или в документации Mozilla Developer Network. Кроме того, если не указано иное, каждый сниппет в этом разделе полагается на следующую простую разметку HTML:

Изучаем CSS3

Изучаем CSS3

Это образец контента. Не читайте его. Вы просто потратите время. Почему вы продолжаете читать? Мне что, нужно использовать Lorem Ipsum, чтобы остановить вас? Чтож, пожалуйста. Lorem ipsum dolor sit amet, consectetur adipi sicing elit, sed do eiusmod tempor incidi dunt ut labore et dolore magna aliqua. Читаете? Черт возьми, вы невыносимы. Я закончу, чтобы поберечь вас.

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

 

Веб-типографика и техники работы с текстом

 

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

Но CSS3 меняет все. У вас никогда не было лучшего повода отойти от базовых шрифтов и расширить горизонты оформления. Перейдем к теме о том, как добавить ритма в вашу типографику с помощью величины шрифта в относительных единицах rem, эксперимента с новыми шрифтами, контролем переноса слов, и как полностью улучшить ваш текст. Тем не менее самый важный элемент на странице – это все-таки текст, и он заслуживает особого внимания.

 

Представляем REM

 

Если у вас есть некоторый опыт с работы с тянущимися макетами, то наверняка вы пользовались единицами em. В силу того что em – это краеугольные камни адаптивного веб-дизайна, их использование может бытьсложным. Они основываются на размере текущего шрифта элемента (или его родительского элемента в случае font-size), поэтому тут нужно вспомнить математику, чтобы рассчитать размер 1 em. Но будем смотреть правде в глаза, математику любят не все.

Новая единица rem (“root em”) – близкий родственник em, с теми же плюсами, только более легкая в использовании. Величина rem устанавливается по размеру шрифта в корневом элементе (это тег для языка HTML). Поэтому 1 rem всегда одного размера, и неважно, где вы ее ставите в документе.

Чтобы rem, как и пиксели, было проще использовать, вы можете установить размер шрифта элемента в 62,5 %, который будет пересчитан в 10 px, если только пользователь не настроил размер шрифта по умолчанию.

Теперь, когда вы задаете длину в rem, вы можете просто умножить на 10, чтобы получить величину в пикселях. Так как 10 пикселей может быть слишком мало для основного текста, вы можете настроить какой хотите размер rem в элементе . Потом эту величину унаследуют все элементы. Например, если вы хотите, чтобы размер текста «тела» был 15 пикселей, можете сделать следующее:

html { font-size: 62.5 %; }

body { font-size: 1.5rem; /* 15px */ }

Один единственный недостаток величин rem – их поддерживают все основные браузеры, кроме Internet Explorer (IE) 8 и его ранних версий. Как альтернативу используйте каскадность стилей и установите размер в пикселях до настройки его в rem. Это может значительно увеличить вашу таблицу стилей. Поэтому вы можете использовать раздельную таблицу стилей с условными комментариями к IE 9 и его ранним версиям, если только вам не нужна поддержка iOS 3.2, Safari 4 и старых версий Opera.

 

Задание ритма в rem

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

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

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

Для начала мы должны настроить ритм страницы. Например, на следующей странице мы установили его в 2.3 rem или 23 пикселя. Он задается в элементе body с использованием свойства line-height. Мы также установили размер шрифта (font-size) в 1.5 rem, для того, чтобы все основные элементы типографики, кроме заголовков унаследовали его.

Удобно иметь под рукой визуальные направляющие, чтобы видеть, где вы слегка перескочили. Для этого мы создали изображение в формате SVG для показа линий с 23-пиксельными интервалами. Также мы использовали базовый сброс стилей для удаления отступов и полей, чтобы они не нарушали наш ритм:

html {

font-size: 62.5 %;

background: url(line.svg) no-repeat;}

/* reset */

body, div, dl, dt, dd, h1, h2, h3, h4, h5, h6,pre, p, th, td,

article, section, figure, img {

margin: 0;

padding: 0;

}

body {

font-size: 1.5rem;

line-height: 2.3rem;

}

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

 

Заставляем заголовки соответствовать ритму

Настройка параграфов была несложной, так как каждая строка текста имеет междустрочный интервал (line height) меньше, чем 23-пиксельный вертикальный ритм страницы. Но что нам делать с такими элементами, как заголовки, которым нужен размер шрифта больше, чем высота нашей строки или дополнительные отступы сверху и снизу? Мудрость здесь в том, чтобы создать комбинацию из верхнего и нижнего отступов, при этом нужно, чтобы междустрочный интервал был кратен нашему ритму:

h2 {

font-size: 2.6rem; КОД (CODE)

line-height: 4.6rem; /* две базовых величины */

margin: 2.3rem 0 0 0; /* величина ритма сверху и снизу */

}

h3 {

font-size: 2.1rem;

line-height: 2.3rem; /* базовыйритм */

margin: 2rem 0.3rem 0; /* 2 сверху + 0.3 снизу == базовый ритм

}

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

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

Если бы мы использовали величины em в этом примере, нам нужно было бы пересчитать высоту строки и отступы (margin), с учетом размера текста. С rem мы почти полностью можем игнорировать размер шрифта, только надо удостовериться, что высота строки достаточна, чтобы включить текст без нахлеста.

 

GEORGIA у меня на уме

 

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

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

 

Добавить свой собственный @font-face

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

Как только вы выберете шрифт, нужно будет подготовить его в правильном формате и загрузить его через правило @font-face. Мы открыли лучший способ – использовать бесподобный сервис Font Squirrel. Он позволяет загружать шрифт, потом «выдает» его в нужных вам форматах, с правилом @font-face внутри. Все, что о вас требуется, это перенести шрифты на ваш сервер, скопировать код в вашу таблицу стилей, а потом обращаться к шрифту, когда захотите.

Для примера в этом разделе мы взяли шрифт Museo Sans 500 для текста в body и Museo 700 для заголовков. Их предоставил Jos Buivenga абсолютно бесплатно. Давайте посмотрим на код CSS, созданный сервисом Font Squirrel для шрифта Museo 700:

@font-face {

font-family: ‘Museo-700’;

src: url(‘1F9920_0_0.eot’);

src: url(‘1F9920_0_0.eot?#iefix’) format(‘embedded-opentype’),

url(‘1F9920_0_0.woff’) format(‘woff’),

url(‘1F9920_0_0.ttf’) format(‘truetype’);

}

Свойство font-family дает имя шрифта, на которое вам нужно будет сослаться в остальной таблице стилей, а свойство src ссылается на сам шрифт. Браузер будет проверять каждый URL по очереди, пока не найдет поддерживаемый формат. Изначально свойство src должно поддерживать старые версии IE, в которых наблюдается баг при использовании стандартного правила. Если вы вставляете его в свою таблицу стилей, вы можете ссылаться на шрифт обычным способом:

h2 {

font-family: “Museo-700”, serif;

}

Все должно быть в порядке, но вам нужно быть в курсе дополнительных деталей. Шрифт имеет плотность 700, что уже говорит о его жирном начертании. Запомните, по умолчанию браузеры будут считать, что шрифты, которые вы определяете в @font-face, это шрифты без выделения, курсива и без всяких остальных шрифтовых прибамбасов. Если вам нужен элемент со свойством font-weight: bold, он будет искусственно сделан полужирным начертанием. Так как шрифт Museo используется для заголовков, он уже выделен полужирным начертанием. Если вы наслоите на него искусственное полужирное начертание, то получится грязное месиво. Чтобы этого не случилось, мы должны сообщить в правило @font-face, что шрифт уже полужирный, с помощью дескриптора font-weight:

@font-face {

font-family: ‘Museo-700’;

font-weight: bold;

}

Теперь современные браузеры будут знать, что это – полужирный шрифт и больше не станут пытаться сделать его полужирным сами. Добавляя правила @font-face с тем же свойством font-family, но с разными величинами для font-weight, font-style и font-stretch, вы можете объединять многочисленные шрифтовые файлы в одно имя шрифта. Тогда браузеры будут использовать правильный шрифт, когда нужно переключиться с полужирного начертания на курсивное.

 

Используем шрифтовые онлайн-сервисы

Вы можете пользоваться одним из доступных онлайн шрифтовых сервисов, вместо того, чтобы поддерживать свой собственный. Наиболее популярны Google Web Fonts для бесплатных шрифтов и TypeKit – для тех, что предоставляются по подписке. Часто такие подписные сервисы – единственный законный путь получения доступа к известным коммерческим шрифтам.

Рисунок 4.1. Прекрасный ритмичный шрифт с использованием вертикального ритма и атрибута @font-face

Каждый сервис имеет свой собственный способ подключения шрифтов. В нашем случае мы использовали Google Web Fonts для основного заголовка страницы. Google представляет три способа: через тег link, через @import и через JavaScript. Мы остановились на использовании тега link и добавили его в шапку документа как:

Типографикаввек CSS3

css?family=Abril+Fatface’

rel=’stylesheet’ type=’text/css’>

Потом в таблице стилей шрифт может указываться, как раньше, по имени “Abril Fatface”:

h1 {

font-family: “Abril Fatface”;

font-weight: normal;

}

В этом случае мы настраиваем обычное начертание шрифта, потому что Firefox пытается искусственно сделать полужирным уже полужирный шрифт.

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

 

Встречайте нового члена семейства, используя FONT-STRETCH

Свойство font-stretch возможно имеет самое неудачное название в CSS.

Оно не расширяет шрифт искусственно, но взамен позволяет вам использовать растянутое и уплотненное начертание шрифта в гарнитуре. К примеру, если вы захотите использовать шрифт Helvetica Neue Condensed без свойства font-stretch, вам нужно будет подключить его как веб-шрифт (необходима лицензия) и обозначить его под другим именем в шрифтовом семействе. С font-stretch это делается проще:

h1 {

font-family: “Helvetica Neue”;

font-stretch: condensed;

}

Большинство шрифтов не имеют узкого или широкого начертания, так что при использовании другого шрифта, не Helvetica, вам, вероятно, придется подключать его как веб-шрифт. Свойство font-stretch имеет такие значения: normal, ultra-condensed, extra-condensed, condensed, semi-condensed, semi-expanded, expanded, extra-expanded и ultraexpanded. Браузер применит значения к ближайшему подходящему начертанию в семействе. В случае с Helvetica Neue ОС X все сжатые значения отображаются как Helvetica Neue Condensed до тех пор, пока вы не установите дополнительные шрифты.

 

Перенос слов

Мы привыкли видеть текст в вебе выровненным по левому краю с рваным правым. При печати часто применяется выравнивание вместе с переносами, чтобы избежать «рек» в тексте (больших пробелов между словами и символами). Не так давно перенос был недоступен в Сети. Но сейчас все меняется. Свойство hyphens (перенос) доступно с префиксами в Safari (с версии 5.1) и Firefox, и в IE 10.

В примере ниже мы настроили выравнивание текста по всей ширине и автоматический перенос:

Рисунок 4.2. Пример параграфа с переносом (слева) и без переноса (справа)

p {

text-align: justify;

hyphens: auto;

}

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

Вот пример с переносом (слева) и без (справа). Обратите внимание на неровные интервалы между словами во второй и шестой строках текста без переносов.

 

Журнальная верстка

 

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

Доработаем пример выше с использованием колонок, чтобы попробовать, каково это.

 

Определение колонок

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

Количество колонок может устанавливаться свойством column-count, которое допускает своей величиной целое число. Мы также применим такой интервал между колонками, чтобы они располагались красиво. В этом нам поможет свойство column-gap:

article> section > section {

column-count: 2;

column-gap: 2.6rem;

}

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

 

Размещаемся в нескольких колонках

Часто бывает нужно, чтобы текст или элементы, такие как изображения, охватывали несколько колонок. Это можно достигнуть с помощью свойства column-span. В настоящее время можно все или ничего: вы можете либо охватить все колонки, используя значение all или не охватывать вообще, применяя значение none. Определить точное число охватываемых колонок невозможно. В нашем примере заголовки h3 охватывают полную ширину колонок.

h3 { column-span: all; }

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

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

Рисунок 4.3. Верхняя колонка как при журнальной верстке. Текстовый блок в верхней части захватывает ширину нескольких колонок в нижней части

 

Техники верстки/компоновки

 

Пожалуй, самое сложное на сегодняшний день при работе с CSS – это разметка страницы. Что-то вроде простейшей центровки элемента на странице бывает ужасно сложно сделать. Вы можете поседеть (если не уже), когда верстаете двух– или трехколонный макет с равными по высоте колонками. Эти моменты сводятся к тому, что CSS на самом деле никогда не предоставлял способ разбивки страниц. Годами мы неправильно использовали формат, основанный на свойстве float, но это только один хак. Как таблицы, так и свойство floats, не разрабатывались для разметки страницы. Они создавались для обтекания изображения внутри текстового блока. А когда нам не хватает подходящих инструментов, мы импровизируем. Мы должны быть благодарны скромному свойству float за помощь нам все эти годы. Теперь с CSS3 мы можем попросить float подвинуться, потому что у нас есть новые инструменты для этого. Они из самых многообещающих – создание сетки с помощью тянущихся блоков.

 

Разметка с помощью тянущихся блоков

Flexible Box Layout (или Flexbox) – это новая блочная модель, оптимизированная под дизайн интерфейса. Дети блока, настроенные для использования модели Flexbox, располагаются вдоль горизонтальных либо вертикальных осей. Их ширина увеличивается или сокращается для того, чтобы заполнять имеющееся пространство на основе назначенной гибкой длины.

Flexbox имеет историческое прошлое. Сначала оно представляло собой свойство для XUL Mozilla (расширенного языка пользовательского интерфейса) и переписывалось тысячи раз. Спецификация только сейчас достигает зрелости, а у нас есть довольно полная поддержка в WebKit и ночных сборках Chrome. Об этом, вне сомнения, полезно знать. Потому что спецификация, возможно, будет реализовываться быстро, если это уже не произошло до того, как вы об этом прочитали. В особенности с быстротой графика релизов Chrome и Firefox.

 

Пример: Горизонтальная и вертикальная центровка, или Священный Грааль веб-дизайна

Расположить элемент по центру страницы, это, возможно, номер один среди всех запросов веб-дизайнеров. Он, пожалуй, даже превосходит запрос, как положить конец страданиям IE 6. С Flexbox это очень просто.

Начнем с основного шаблона HTML, с заголовка, который мы хотим разместить по центру:

Центровка элемента на странице

OMG, Я в центре

Ничего особенного здесь нет, даже оборачивающего div. Вся магия заключается в CSS:

html {

height: 100 %;

}

body {

display: flexbox; /* это значение нуждается в префиксе */

flex-align: center; /* это свойство также */

flex-pack: center;

margin: 0;

height: 100 %;

}

h1 {

display: flexbox;

flex-align: center;

height: 10rem;

}

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

По той же причине мы выбросили префиксы. Только WebKit поддерживает их (префиксом -webkit-), но не удивляйтесь, если в ближайшем будущем это тоже будут делать и Mozilla, и Opera и IE. Лучше добавлять префиксы на всякий случай. Давайте посмотрим на CSS для выравнивания по центру заголовка на странице. Сначала мы устанавливаем элементы html и body на 100 % высоты и убираем любые отступы. Это поможет контейнеру нашего h1 полностью принять высоту окна браузера. Теперь нам просто все нужно расположить по центру.

 

Включаем FLEXBOX

Так как элемент body содержит заголовок, который мы хотим поставить по центру, мы задаем значение свойства display на flexbox:

body {

display: flexbox;

}

Это заставляет элемент body применять разметку Flexbox вместо обычной блочной. Все его дети в потоке документа (т. е. не абсолютно спозиционированные элементы) становятся элементами Flexbox.

Чего же мы добьемся тем, что наши элементы сделались гибкими, словно от занятий йогой? Они приобретают неслыханную силу: могут изменять свой размер и позицию относительно имеющегося пространства, могут располагаться и вертикально, и горизонтально, и даже могут достичь независимости позиционирования от положения в коде. (Два Священных Грааля в одной спецификации? Да у нас все хорошо!)

 

Центровка по горизонтали

Идем дальше. Мы хотим расположить наш элемент h1 по центру горизонтально. Раз плюнуть, скажете вы. Да, это, в общем-то, проще, чем «играть» с автоматическими отступами. Всего-то и надо дать команду Flexbox расположить по центру его элементы. По умолчанию элементы Flexbox распределятся горизонтально, поэтому установка свойства flex-pack выровняет элементы вдоль основной оси:

Рисунок 4.4. Простая горизонтальная и вертикальная центровка с использованием Flexbox

body {

display: flexbox;

flex-pack: center;

}

Другие возможные значения – это start (начало), end (конец) и justify (по всей ширине). Значение start выравнивает влево (или вправо, если текст идет справа налево), end выравнивает справа, а justify четко распределяет элементы вдоль оси.

Если вы хотите точно установить ось, вдоль которой выравнивается элемент, то можете сделать это с помощью свойства flex-flow. Стандартная настройка – горизонтальная, она даст нам тот же эффект, которого мы только что добились. Чтобы сделать выравнивание по вертикальной оси, мы можем использовать свойство flex-flow: column. Если мы добавим его в наш пример, вы заметите, что элемент лег по центру вертикально, но мы потеряли горизонтальную центровку. Реверсирование порядка при добавлении -reverse к значениям row или column также возможно (flex-flow: row-reverse или flex-flow: column-reverse), но в нашем примере это мало что значит, так как у нас всего один элемент.

 

Центровка по вертикали

Центровка по вертикали такая же простая, как и горизонтальная. Все, что нам надо, это применить подходящее свойство для выравнивания поперечной оси. Выравнивания чего?! По существу, поперечная ось – это неосновная ось. Поэтому если элементы Flexbox выравниваются горизонтально, то поперечная будет вертикальная, и наоборот. Мы делаем эти настройки с помощью свойства flex-align:

body {

display: flexbox;

flex-pack: center;

flex-align: center;

}

Вот и все, что нужно для центровки элементов с Flexbox! Мы также можем использовать значения start и end, и baseline, и stretch. Давайте посмотрим конечный результат. Зайдите для этого по адресу .

Как вы могли заметить, текст также расположен вертикально по центру внутри элемента h1. Это можно было бы сделать отступами (margins) и междустрочным интервалом (line height), но мы снова использовали Flexbox, чтобы показать, как это работает с блоками (в этом случае линия текста лежит внутри элемента h1). Неважно, какой высоты элемент h1, текст всегда будет в центре:

h1 {

display: flexbox;

flex-align: center;

height: 10rem;

}

 

Гибкость в размерах

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

Рисунок 4.5. Интерактивное слайд шоу, созданное с использованием flex-order

HTML и CSS для этого примера идентичны предыдущему. Мы подключаем Flexbox и центрируем элементы на странице тем же способом. Вдобавок к этому, мы хотим сделать так, чтобы заголовок (внутри элемента header) не изменял свой размер. При этом пять блоков (элементы section) нам нужно подогнать по размеру, чтобы заполнить ширину окна. Для этого мы используем новую функцию flex как значение свойства width:

section {

/* чтобы сэкономить место, мы убрали остальной код */

flex: 1;

height: 250px;

}

То, что мы сейчас сделали, это заставили каждый элемент section стать равным одной единице flex. Так как мы не задали точную ширину, каждый из пяти блоков будет иметь равную. Элемент header примет установленную ширину (277 пикселей), так как он негибкий. Мы разделим оставшуюся внутри элемента body ширину на 5, чтобы рассчитать ширину каждого элемента section. Теперь если мы изменим размеры окна браузера, они или увеличатся, или уменьшатся.

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

Рисунок 4.6. Интерактивное слайд шоу, созданное с использованием Flexbox

section: hover {

flex: 2;

cursor: pointer;

}

Теперь имеющееся пространство делится на 6, а не на 5, и элемент, на который навели курсор, будет равняться двойной базовой величине. Обратите внимание, что элементу с двумя единицами flex не обязательно удваиваться по ширине, по сравнению с тем, у которого одна единица. Он становится вдвое больше, чтобы занять имеющееся пространство, которое добавлено к его «предпочтительной ширине». В наших примерах «предпочтительная ширина» равна 0 (по умолчанию).

 

Независимый источник порядка

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

Все, что нам нужно, это настроить порядок с помощью свойства flex-order. По умолчанию, все flex-элементы в нулевой позиции. Из-за того что они имеют одинаковую позицию, они располагаются согласно расположению в коде.

Чтобы выбранный нами элемент переместился на первую позицию, нам просто надо задать меньшую цифру. Мы выбираем -1. Нам еще нужно задать заголовку -1 так, чтобы выбранный элемент не «выскочил» до него:

header {

flex-order: -1;

}

section[aria-pressed=”true”] {

flex-order: -1; /* меньше, чем 0, поэтому идет перед другими элементами section

*/

flex: 3;

max-width: 370px; /* ограничивает от слишком большого расширения*/

}

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

 

Работа с изображениями

 

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

 

Множественные фоны и градиенты

Взгляните на следующий стиль в двух разных размерах:

Рисунок 4.7. Широкий вариант множественных фонов и градиентов

Рисунок 4.8. Узкий вариант

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

html {

background: #222;

min-height: 100 %;

}

body {

margin: 0;

}

section {

max-width: 25em;

margin: 0 auto;

padding-top: 150px;

color: white;

font: italic 100 %/1.5 ‘Palatino Linotype’, Georgia, serif;}

Но как добавлять звезды, силуэты на фоне неба и луну? Мы используем только два элемента (html и body – элемент section слишком узкий), а нам нужно четыре фоновых рисунка.

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

html {

background: url(“moon.png”) no-repeat 100 % 1em,

url(“stars.png”) repeat-x 0 0,

url(“city.png”) repeat-x bottom,

linear-gradient(black, #444);

background-color: #222;

min-height: 100 %;

}

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

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

html {

background: url(“moon.png”) no-repeat 100 % 1em,

url(“stars.png”) repeat-x 0 0,

url(“city.png”) repeat-x bottom;

background: url(“moon.png”) no-repeat 100 % 1em,

url(“stars.png”) repeat-x 0 0,

url(“city.png”) repeat-x bottom,

linear-gradient(black, #444);

background-color: #222;

min-height: 100 %;

}

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

html {

background: #222;

background: linear-gradient(black, #444);

height: 100 %;

}

body {

margin: 0;

background: url(“stars.png”) repeat-x 0 0;

background: url(“moon.png”) no-repeat 100 % 1em,

url(“stars.png”) repeat-x 0 0,

url(“city.png”) repeat-x bottom;

min-height: 100 %;

}

Намного лучше, и дает отдачу от возможностей каждого браузера.

 

Свойства BACKGROUND-ORIGIN, BACKGROUND-SIZE, OUTLINE

Рисунок 4.9. Дизайн, который мы будем воспроизводить на CSS3

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

html {

min-height:100 %;

background: url(‘rainbow-wood.jpg’);

}

section {

max-width: 25em;

padding: 3em;

margin: 4em auto;

background: black url(logo.svg) no-repeat bottom right;

color: white;

font: bold 100 %/1.5 sans-serif;

text-shadow: 0 – .1em .2em black;

}

h1 {

margin-top: 0;

}

Результат близок к тому, которого мы добивались. Но есть проблемы:

• Фоновое изображение элемента html – гигантское. Это хорошо для огромных экранов, но, как правило, мы хотим подогнать размер под экраны поменьше.

• Розовый логотип слишком мал и прилеплен к правому нижнему углу без отступа от края.

• Нет розовой «строчки».

Разберем эти вопросы по порядку.

Рисунок 4.10. Результат после применения наших знаний о CSS2.1

 

Изменяем размер фонового рисунка по ширине

CSS3 дает нам новое свойство для контроля размера фонового изображения: background-size. Это позволяет нам использовать одно и то же изображение в разных размерах. Мы можем либо установить точно определенный размер, либо применить один из двух ключевых слов для задания размера: contain и cover.

• cover

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

• contain

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

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

 

Правим логотип

Для увеличения размера SVG логотипа мы снова используем свойство background-size, но на этот раз устанавливаем точный размер:

background-size: 150 px;

При задании только одного значения вместо двух мы сохраняем соотношение сторон, при этом изображение расширяется до 150 пикселей по ширине. Но оно все еще «приклеено» к низу. В прежние времена мы бы просто пожали плечами и отредактировали изображение так, чтобы в нем был промежуток. Сегодня с CSS3 у нас есть немного больше контроля при размещении изображения. Если проанализировать примеры выше более детально, мы столкнемся с проблемой – изображение находится внизу справа от области полей, но нам хотелось бы, чтобы оно располагалось внизу справа от текста. CSS3 дает нам новое свойство background-origin, которое контролирует позиционирование изображения относительно края элемента с учетом толщины рамки, относительно рамки, либо содержимого элемента.

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

background-origin: content-box;

 

Добавление розовой строчки

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

border: 1px dashed #f06;

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

border: 1px dashed #f06;

outline: 20px solid rgba(0,0,0,8);

Другой способ – использовать свойство outline со значением outline-offset в -20px (здесь мы не применяем эту технику). Вот полный сниппет:

html {

min-height:100 %;

background: url (‘rainbow-wood.jpg’);

background-size: cover;

}

section {

max-width: 20em;

padding: 3em;

margin: 4em auto;

border: 1px dashed #f06;

outline: 20px solid rgba(0,0,0,8);

background: url(logo.svg) no-repeat bottom right;

background-color: black;

background-color: rgba(0,0,0,8);

background-origin: content-box;

background-size: 150px;

color: white;

font: 100 %/1.5 sans-serif;

text-shadow: 0 – .1em .2em black;

}

h1 {

margin-top: 0;

}

 

Обрезание фона

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

Рисунок 4.11. Полупрозрачная рамка с обрезанием фона

Для получения такого результата вы, вероятно, попробуете что-то подобное:

html {

min-height: 100 %;

background: url(‘rainbow-wood.jpg’) top;

background-size: cover;

}

section {

max-width: 20em;

padding: 3em;

margin: 4em auto;

border: 20px solid rgba(0,0,0,5);

background-color: black;

color: white;

font: 100 %/1.5 sans-serif;

text-shadow: 0 – .1em .2em black; }

h1 {

margin-top: 0;

}

Рисунок 4.12. На самом деле наша граница не полупрозрачная. Почему?

Но когда вы попробуете, то увидите, что граница по факту не полупрозрачная. Почему так произошло? Причина в том, что по умолчанию фон также растягивается по границе. Вспомните все те разы, когда вы применяли стили рамки с пробелами (т. е. точечные, пунктирные и удвоенные) в дни существования CSS2.1? Это то же самое, но только сейчас у нас есть средства контроля поведения, а именно свойство background-clip. Его значение по умолчанию – border-box, результат которого аналогичен предыдущему опыту. Но мы должны изменить его на padding-box:

background-clip: padding-box;

Это заставит фон обрезаться точно там, где нам надо.

 

Граница рисунка

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

Рисунок 4.13. Пример рамки

Рисунок 4.14. Изображение cloth.svg, с которым мы и будем работать

Свойство border-image – новое и мощное, дает нам возможность использовать одно маленькое изображение и для фона, и для рамки элемента. Мы определяем, каков его масштаб и как оно повторяется. Они должно отличаться для каждого края. В этом примере мы использовали рис. 4.14.

А вот код CSS, который идет для него:

html {

min-height:100 %;

background: white url(background.jpg);

}

section {

max-width: 20em;

padding: 3em;

margin: 4em auto;

border: 20px solid transparent;

– webkit-border-image: url(cloth.svg) 33.33 % round;

– moz-border-image: url(cloth.png) 33.33 % round;

– o-border-image: url(cloth.svg) 33.33 % round;

border-image: url(cloth.svg) 33.33 % round fill;

font: 100 %/1.5 sans-serif;

text-shadow: 0 1px white;

}

h1 {

margin-top: 0

}

Свойство border-image определяет, какое изображение будет использовано, какой должна быть ширина каждого «кусочка» (в этом случае мы хотим разрезать по три части, как горизонтально, так и вертикально, это лишь одна цифра) и как эти «кусочки» должны повторяться или растягиваться (ключевое слово round повторяет рисунок и масштабирует его так, чтобы на стороне элемента оказалось целое число изображений.). Ключевое слово fill сохраняет средний кусочек в виде фона, но оно не поддерживается браузерными префиксами. К счастью, у свойств с браузерными префиксами это поведение есть по умолчанию. Вы также можете заметить, что мы используем SVG (масштабируемую векторную графику) в каждом браузере, кроме Firefox. Дело в том, что в момент написания этого раздела Firefox «глючит» при применении SVG-картинок для рамок. Но Mozilla работает над этим. Хотите, проверьте сами.

Когда мы используем свойство border-image, стиль и цвет рамки, который мы определяем, игнорируется до тех пор, пока стиль рамки не устанавливается до значения none. Только свойство border-width имеет эффект. Но мы хотим задать что-то вроде solid transparent, так чтобы когда border-image не поддерживается, у нас не было бы уродливо-толстой рамки. Вы можете варьировать расстояние, а в некоторых случаях «реальный» запасной вариант рамки лучше, чем ничего.

 

Преобразования (трансформации)

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

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

Применение простой трансформации

В примере каждый рисунок включен в элемент figure, как здесь:

””

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

figure {

float: left;

z-index: 1;

margin: 1rem;

width: 160px;

height: 160px;

transition-duration: 1s;

transform: scale(0.25);

}

Свойство transform допускает в качестве значения разделенный пробелами список функций трансформирования. Здесь мы используем функцию scale для уменьшения размера элемента вчетверо. Масштабирование пойдет от центра элемента по умолчанию. Значения меньше 1 уменьшат масштаб элемента, а значения выше этой цифры – увеличат.

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

После применения дополнительных стилей к body и самим изображениям, мы получим что-то наподобие следующего:

Рисунок 4.15. Простая галерея изображений без трансформаций

 

Применение дополнительных трансформаций

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

figure: hover {

transform: scale(0.33) rotate(2deg);

z-index: 100;

cursor: pointer;

}

Здесь мы применяем два преобразования. Любое количество трансформаций может применяться при задании их через список, разделенный пробелами. Здесь мы уменьшаем масштаб рисунка в 3 раза, затем поворачиваем его на 2 градуса. Функция rotate перемещает элемент вокруг оси по часовой стрелке. Чтобы перемещение было против часовой стрелки, мы используем отрицательную величину:

figure: nth-of-type(even):hover {

transform: scale(0.33) rotate(-2deg);

}

Рисунок 4.16. Преобразование, применяемое для изображения по наведению курсора с использованием CSS3

Каждая функция transform применяется по очереди, поэтому элемент сначала масштабируется, а потом вращается. Помните, что это важно! Порядок влияет на размер элементов при изменении масштаба, и на направление каждой оси при повороте.

Так как все функции transform применяются с использованием одного свойства, а вы хотите просто переместить одну величину, вам нужно будет составить полный перечень. А иначе остальные величины примут свои значения по умолчанию. При наведении курсора на изображение в нашем примере, оно будет масштабироваться и поворачиваться. Вы можете заметить, что изображение, которое находится после того, на которое наведен курсор, также перемещается и трансформируется после короткой паузы. Здесь мы добавили преобразование translateX, которое смещает элемент вдоль оси X.

figure: hover + figure {

transform: scale(0.25) rotate(-1deg) translateX(15px);

transition-duration: 1.5s;

transition-delay: .2s;

}

Вы видите, что нет строгого движения вдоль оси X или преобразования на 15 пикселей, потому что преобразование scale уменьшает длину на четверть, а преобразование rotate поворачивает ось X на 1 градус против часовой стрелки.

Функция translateX принимает одно значение, используя действующую длину элемента. Также существует соответствующая функция translateY. Они обе могут устанавливаться вместе с использованием функции translate, которая допускает две величины (сначала X, затем Y), которые разделяются запятой.

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

 

Настройка базы трансформаций

Все трансформации в примере используют исходную точку по умолчанию, которая является центром элемента. Использование свойства transform-origin поможет установить ее. Оно допускает от одной до четырех величин, заданных через пробел. Это может быть длина, процент, или ключевые слова «сверху, слева, снизу, справа или в центре». Если установлена только одна величина, то вторая по умолчанию будет в центре. Если одна из величин не является ключевым словом, то тогда первая будет отвечать за горизонтальную позицию. При использовании ключевого слова, вы можете определить дополнительную величину смещения, которая устанавливается как процент или длина сразу после этого:

transform-origin: top 10 % left 25 %;

Так база преобразований установится на точке, которая находится на пересечении 10 % от верха элемента и 25 % слева от него.

 

Селекторы

 

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

 

Подсвечивание текущего элемента

Давайте вспомним пример с вертикальным ритмом из раздела о типографике. Вы, возможно, в курсе, что можете ссылаться на определенные разделы страницы, используя идентификатор с решеткой после указателя URL. Так мы можем использовать что-то вроде этого http://example.com/index.html#def для ссылки на раздел с определениями типографики. Когда на странице несколько больших разделов, пользователю сразу же видно, в какой раздел он попал.

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

В прошлом для выполнения этой операции нам бы понадобился язык JavaScript. CSS3 дает нам новый псевдокласс для указания текущего элемента, т. е. элемент, чей ID-атрибут совпадает с текущим хешем в URL. Этот псевдокласс называется: target.

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

h1:target, h2:target,

h3:target, h4:target,

h5:target, h6:target {

background: hsla(65,100 %,50 %,5);

}

Указание цвета в профиле HSLA не нужно в данном случае, потому что в общем любой браузер, который поддерживает псевдокласс: target также поддерживает цвета HSLA. Старые браузеры, которые не поддерживают: target на самом деле не проблема, так как селектор улучшает юзабилити и его функциональность не ключевая. Википедия использует: target, когда вы щелкаете на сноску, подсвечивая ее в (обычно длинном) списке ссылок. Это реально помогает вам быстро опознать правильную ссылку, так ведь?

 

Указание на элементы, основанные на их позиции в DOM (объектной модели документа)

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

В CSS 2.1 у нас был только один структурный псевдокласс: first-child. CSS3 расширяет это и дает нам изобилие новых псевдоклассов, что решает не только перечисленные задачи, но и другие вопросы:

• nth-child

• last-child

• nth-last-child

• only-child

• first-of-type

• nth-of-type

• last-of-type

• nth-last-of-type

• only-of-type

Количество псевдоклассов в этом списке может испугать, но как только вы поймете возможности: nth-child и как это работает, вы легко уловите все остальные и узнаете, как это применять. Потому что это всего лишь варианты или ярлыки. Те, что начинаются с nth, представляют концепцию, которой не было в CSS 2.1: псевдоклассы с параметрами. Подобно функциям, они задают параметр, который дифференцирует их поведение, в круглых скобках. Синтаксис этого параметра может быть следующим:

• Число в: nth-child(1) равно псевдоклассу: first-child в CSS 2.1.

• Чтобы выразить: nth-child(5) в CSS 2.1, вам нужно было бы написать: first – child + * + * + * + *, что недопустимо многословно, особенно для больших цифр.

• Выражение типа 5n или 3n+2, где n равно любому числу от 0 до бесконечности. Например, nth-child(3n+1) равно: nth-child(1), nth-child(4), nth-child(7), nth-child(10) и т. д., с бесконечным списком.

• Одно из ключевых слов нечетное или четное, 2n+1 и 2n, соответственно.

Например, чтобы затемнить фон каждой нечетной строки таблицы, мы могли бы написать что-то наподобие:

tr: nth-child(odd) {

background: rgba(0,0,0,15);

}

Это, по существу, эффект полосок зебры, для которого мы обычно используем JavaScript.

Пожалуйста, обратите внимание на то, что разница между: nth-* и: nth-last-* – это чисто направление нумерации :nth-child начинается от первого «родителя», тогда как: nth-last-child стартует от последнего. Отсюда :last-child по существу равен: nth-last-child(1), а :only-child равен :first-child: last-child, потому что он подходит к элементам без «братьев и сестер». Интересно то, что мы можем обобщить псевдокласс: only-child так, что когда нам нужно обратиться к элементу ровно с пятью дочерними элементам, мы можем использовать: first-child: nth-last-child(6), чтобы обратиться к первому, а затем применить: first-child: nthlast– child(6) ~ * для остальных.

Разница между псевдоклассами *-child и *-of-type в том, что последний поддерживает отдельный счет на тег. Например, body: first-child никогда не совпадет, потому что body всегда имеет заголовочный дочерний элемент, а body: first-of-type всегда совпадает, так как у нас всего один элемент body.

Это может быть не особо важно (не очень значимо) для позиционирования body, но чрезвычайно полезно, если мы хотим обратиться, предположим, к каждому третьему изображению в разметке, у которой переменное количество параграфов между изображениям. В этом случае псевдокласс: nth-child рендерился бы непоследовательно, потому что он действует со всеми дочерними элементами, независимо от их типа.

 

Что насчет старых браузеров?

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

Наиболее популярный на данный момент – это Selectivizr.

 

Сочетаем элементы без проблем

Итак, давайте снова вернемся к примеру в разделе о работе с изображениями. Предположим, нам сейчас надо заменить статической текст на веб-форму с текстом, который находится в элементе textarea, что позволяет людям редактировать его. Мы даем нашему элементу textarea внутренние поля в 1 em, 1-пиксельную рамку и ширину 100 %, потому что мы хотели чтобы он занял всю ширину контейнера. Вы, вероятно, видите, к чему это ведет – к Старой Ужасной Проблеме с Процентами в CSS™.

Поля и рамки добавляются к тем 100 %, которые делают весь прямоугольник (блок) намного больше, чем 100 %, и выглядят не так «навороченно». В былые времена нам было бы нужно устанавливать отступы и рамки тоже в процентах, и определять ширину в 100 % минус поле, минус ширина рамки. К счастью, в CSS3 мы властны изменять способ, которым рассчитывается ширина, и делать это так, как естественно для нас – включать в ширину поле и рамку. Свойство box-sizing отвечает за это изумительное изменение. Оно принимает три значения:

• content-box

значение по умолчанию, которое мы уже знаем и не любим;

• padding-box

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

• border-box

и отступ, и рамки включаются в ширину.

Рисунок 4.17. Наша отправная точка: стиль из предыдущего раздела

Рисунок 4.18. Старая Ужасная Проблема с Процентами в CSS™

Рисунок 4.19. Смешивание процентов с пикселями и ems с использованием box-sizing

С применением box-sizing: border-box наша проблема теперь решена. И это свойство поддерживается не только каждым современным браузером, но также и IE 8!

 

Перемещения

 

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

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

 

Использование перемещений

Для того чтобы продемонстрировать, как использовать перемещения, мы собираемся провести день на скачках. Помните тот автомат со скачущими лошадками, когда вы были маленькими? Если нет, не расстраивайтесь. Идея проста: лошадки скачут по дороге с разными скоростями, а вы должны угадать какая из них придет первая. Эта игра переделана при помощи перемещений CSS. Вы можете поиграть дома, пройдя по ссылке . Просто наведите курсор на дорожки и смотрите, как скачут лошадки!

Рисунок 4.20. Игра со скачущими лошадками, созданная при помощи перемещений CSS

Разметка для дорожки такова:

TheSmashing Derby

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

#track div {

width: 3em;

height: 3em;

background: url(horse.png) no-repeat right center;

transition-property: width;

transition-duration: 6s;

}

#track: hover div {

width: 40em;

}

Здесь мы говорим, что свойство width должно перемещаться около 6 секунд от 3 ems до 40 ems, когда на дорожку наведен курсор. Свойство transition-property настраивается по умолчанию ко всему, поэтому если вы не установите его точно, оно будет перемещать каждое анимируемое свойство.

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

 

Настройка скорости передвижения лошадей

Скачки не были бы такими забавными, если бы лошади все время неслись с одной скоростью и приходили к финишу одновременно. Что ж, давайте настроим скорость каждой лошадки с помощью свойства transition-timing-function. У всех видов функций расчета времени одинаковая продолжительность до завершения, но их ускорение и замедление происходит на разном уровне, в зависимости от установленной кривой Безье. Не волнуйтесь, если это звучит слишком по-математически: вы можете выбирать из набора встроенных функций расчета времени. Эти предустановки имеют следующие значения ключевых слов:

• ease

это значение по умолчанию;

• linear

перемещения с постоянной скоростью от A до B;

• ease-in

перемещения в медленном темпе, которые ускоряются при приближении к точке B;

• ease-out

перемещения в быстром темпе, которые замедляются при приближении к точке B;

• ease-in-out

перемещения быстрые до точки на полпути, затем замедляются при приближении к точке B.

Каждая из этих функций применяется именно в таком порядке для лошадей из примера:

li: nth-of-type(1) div { transition-timing-function: ease; }

li: nth-of-type(2) div {

transition-timing-function: linear;

}

li: nth-of-type(3) div {

transition-timing-function: ease-in;

}

li: nth-of-type(4) div {

transition-timing-function: ease-out;

} li: nth-of-type(5) div {

transition-timing-function: ease-in-out;

}

Глядя на рисунок можно увидеть, что лошадь 1 (ease) вырывается в лидеры, это – явный победитель. О, нет! Она выбивается из сил на трети до финала. И все пять лошадей пересекают финиш одновременно!

Если вы недовольны предустановками, то можете установить свои собственные, используя кубическую функцию Безье. Для определения кубической функции, вам нужно задать координаты x и y для контрольных точек кривой. Начало всегда фиксируется на 0,0, а конец – на 1,1, поэтому их не нужно определять. Функцию перемещения ease-in можно определить, как показано ниже, с применением кубической функции:

transition-timing-function: cubic-bezier(0.42, 0, 1, 1);

Некоторое количество инструментов, таких как Lea Verou’s Cubic Bezier preview tool, позволят вам визуально задать и «довести до ума» функцию cubic-bezier.

 

Придержите своих лошадей

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

#track div {

transition-property: width;

transition-duration: 6s;

transition-delay: 1s;

}

Со всеми этими свойствами за плечами ваши элементы «пролетят» по странице за два счета!

 

Заключение

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

Пока браузеры «снимают сливки» с CSS3, рабочая группа по CSS уже разрабатывает следующую версию, обычно упоминаемую как CSS4. Ожидается, что это привнесет свойства, которые уже жарко обсуждаются, такие как селекторы родителей, переменные, многоколоночная верстка макета страницы и конусные градиенты.

Восторгаясь от того, что CSS3 и CSS4, возможно, звучат как модные словечки, помните, что в целом живым стандартом является CSS. Каждый член рабочей группы CSS может утверждать, что в веб-стандартах нет таких понятий, как “CSS3” или “CSS4”. На деле, нет больше глобальной версии. После CSS 2.1, CSS была модулирована, и каждый модуль теперь имеет свою версию. И некоторые модули Уровня 1 фактически могли выходить позже, чем модули Уровня 4. Но нам не нужны модные словечки, чтобы приходить в восторг от всего, что приходит в мир CSS, так ведь?

 

Об авторах

* * *

Дэвид Стори имеет степень магистра в области Интернета и Распределенных систем университета Дарема, Великобритания. Член сообщества рабочей группы CSS, он является ярым сторонником открытых веб-стандартов. В настоящее время Дэвид живет в Маунтин Вью, штат Калифорния и работает в компании Motorola Mobility. До этого он работал в Opera, где создал команду разработчиков Developer Relations team и был бренд-менеджером продукта Opera Dragonfly. Так же он работал в ЦЕРН (CERN) – европейском центре ядерных исследований. Являлся автором тестов CSS3.info во времена его золотого периода. Он специализируется на HTML, CSS, SVG и JavaScript.

*****

* * *

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

 

О рецензенте

Тэб Аткинс, мл. Специалист во многих областях. Он работает в Google над разработкой браузера Chrome в качестве хакера веб-стандартов, хотя его вклад в код достаточно скромен. Тэб в основном работает со спецификациями HTML и CSS. Также он является членом сообщества рабочей группы CSS и сотрудничает с несколькими другими рабочими группами в W3C.