Теперь, если пиксели нас устраивают, мы можем перевести значения из оригинал-макета непосредственно в CSS:
 
   h1 {
   font-size: 24px;
   font-style: italic;
   font-weight: normal;
   }
 
   h1 a {
   color: #747474;
   font: bold 11px Calibri, Optima, Arial, sans-serif;
   letter-spacing: 0.15em;
   text-transform: uppercase;
   text-decoration: none;
   }
 
   Нет ничего плохого или неправильного в определении размера текста с помощью пикселей. Но в целях нашего эксперимента давайте начнем думать пропорционально и переведем значения кегля (font-size) из пикселей в относительные единицы, а вместо пикселей и будем использовать знакомые нам em.

Контекстное восстановление

   Сейчас будет немного математики: берем целевое значение кегля и делим на кегль (font size) его контейнера, то есть контекста. В результате мы получаем желаемый кегль, выраженный в относительных и достаточно гибких единицах em.
   Другими словами, относительный кегль можно рассчитать по следующей формуле:
 
   target ÷ context = result
 
   (Отвлечемся на минутку. Лично у меня слово «математика» вызывает немедленный и серьезный приступ паники. У вас тоже? Стойте, не убегайте с криками – все не так страшно. Это говорит вам человек, который заменил курс математики в колледже курсом философии. Делайте, как я: просто посчитайте все на калькуляторе и скопируйте результат в CSS. Калькуляторы – просто спасение для таких, как мы, правда?)
   Итак, формула у нас есть, давайте вернемся к нашему заголовку в 24px. Если предположить, что базовый кегль (font size) элемента body равен 16 пикселям при 100%, мы можем подставить эти значения непосредственно в формулу. В результате получим отношение целевого кегля заголовка h1
   (24 пикселя, 24px) и кегля его контекста (16 пикселей, 16px):
 
   24: 16 = 1,5
 
   Так как 24 пикселя в 1,5 раза больше 16 пикселей, это значит, что кегль равен 1,5 em.
 
   h1 {
   font-size: 1.5em; /* 24px / 16px */
   font-style: italic;
   font-weight: normal;
   }
 
   Вуаля! Размер нашего заголовка прекрасно совпадает с размером, указанным в оригинал-макете, но при этом выражен в относительных, масштабируемых единицах (рис. 2.7).
   (Обычно я оставляю комментарий с расчетами с правой стороны (/* 24px / 16px */). Вносить изменения становится намного проще.)
   С этим закончили, давайте вернемся к нашей одинокой маленькой ссылке Read More (узнать больше). Хотя, если посмотреть на рис. 2.7, она не такая уж и маленькая. И это проблема. Нам нужно уменьшить заданные 11 пикселей, и довольно существенно, поскольку размер его шрифта принял значение 1,5 em от его контекста, h1.
 
   Рис. 2.7. Размер нашего заголовка правильно выражен в гибких, масштабируемых единицах em. (Но что за ерунда творится со ссылкой?)
 
   И вот здесь требуется внимание. Поскольку текст заголовка установлен равным 1,5 em, любые элементы внутри этого заголовка должны быть выражены в виде доли этого значения. Другими словами, изменился наш контекст.
   Поэтому, чтобы установить кегль ссылки в единицах em, мы делим целевые 11 пикселей (11px) не на 16 (значение, установленное в body), а на 24 – кегль заголовка, наш новый контекст:
 
   11: 24 = 0,458333333333333
 
   Мы получили какое-то совсем некрасивое число. Может быть, самое некрасивое, которые вы сегодня видели. (Но подождите, эта глава еще не окончена.)
   Вам захочется округлить его до более-менее приемлемого числа – скажем, 0,46 em. Даже не думайте! Может, ваши глаза и устанут смотреть на 0,458333333333333, но именно это число идеально представляет желаемый кегль в пропорциональном отношении. К тому же браузеры мастерски владеют искусством округления лишних десятичных знаков, когда преобразовывают значения в пиксели. Поэтому нужно дать им больше, а не меньше, и в конце вас будет ожидать отличный результат.
   Теперь просто скопируйте это непритязательное число в CSS:
 
   h1 a {
   font: bold 0.458333333333333em Calibri, Optima, Arial, sans-serif; /* 11px / 24px */
   color:#747474;
   letter-spacing: 0.15em;
   text-transform: uppercase;
   text-decoration: none;
   }
 
   Посмотрим на результат. Наша страничка закончена, она полностью соответствует желаемому дизайну, а текст задан в масштабируемых единицах em (рис. 2.8).
 
   Рис. 2.8. С помощью простой математики мы создали более красивый дизайн – и без всяких пикселей

От гибких шрифтов к гибкой сетке

   Вы, наверное, сейчас зеваете со скуки. Здесь ведь должна была быть глава про гибкие макеты, а этот тип Итан все талдычит про математику и размеры шрифтов. Надоело!
   Но когда я впервые делал гибкую сетку, я понятия не имел, с чего начинать. Поэтому, столкнувшись с неразрешимой проблемой, я сделал то, что у меня получается лучше всего: полностью ее проигнорировал и начал работать над тем, что знаю.
   Когда я понял, как устанавливать размеры текста в единицах em, на меня снизошло прозрение: ведь мы можем применять тот же принцип пропорционального мышления и в отношении самих макетов. Другими словами, все элементы нашей сетки – строки, колонки и накладываемые на них модули – могут быть выражены как пропорция содержащихся в них элементов, а не в неизменных, жестких пикселях.
   И в этом нам снова поможет наша формула target ÷ context = result. Идем дальше.

Создание гибкой сетки

   Представьте, что дизайнер настолько впечатлен вашей быстрой и качественной работой над заголовком, что прислал вам другой макет, и теперь вам нужно написать код для блога сайта Robot or Not (рис. 2.9).
 
   Рис. 2.9. Новое задание – превращение эскиза в гибкий макет
 
   Плюс ко всему дизайнеру настолько понравилась работа, что он прислал краткую схему содержания страницы (рис. 2.10), благодаря чему мы можем не тратить время на планирование. Нужно как-то его отблагодарить.
 
   Рис. 2.10. Схема расположения элементов для нашего блога
 
   Мы можем быстро и ловко перевести его схему в базовую структуру верстки:
 
   <div id="page">
   <div class="blog section">
   <h1 class="lede">Recently in <a href="#">The Bot Blog</a></h1>
   <div class="main">
   …
   </div><!– /end.main – >
   <div class="other">
   …
   </div><!– /end.other – >
   </div><!– /end.blog.section – >
   </div><!– /end #page – >
 
   Наша разметка получилась простой и аккуратной, семантически верной и превосходно подходит для контента. Мы создали основной контейнер для всей страницы (#page), который, в свою очередь, содержит модуль .blog. Внутрь него мы поместили еще два блока: один с классом .main для главного содержания статьи, а второй с классом .other для всего остального. Звучит, конечно, не слишком поэтично, но, с другой стороны, это и не сборник стихов.
   А теперь пропустим несколько этапов – как это делается на кулинарных шоу, где повар кладет в кастрюлю сырые продукты, а через минуту вынимает из духовки полностью готовую индейку. (Эта метафора прекрасно демонстрирует то, как часто я смотрю кулинарные шоу… или готовлю индейку.)
   И все же предположим, что мы уже создали все CSS, связанные со шрифтами, фоновыми изображениями и всеми элементами нашего дизайна, не имеющими отношения к макету (рис. 2.11). Теперь мы можем сосредоточиться исключительно на создании «резиновой» сетки.
 
   Рис. 2.11. Работа над шаблоном закончена! Если, конечно, не принимать во внимание то, как он должен выглядеть в самом конце
 
   Так как же нам превратить эти блоки .main и .other в нужные колонки? У нас уже есть схема контента и основная разметка, теперь давайте внимательнее взглянем на физические параметры сетки в оригинальном дизайне (рис. 2.12).
 
   Рис. 2.12. Теперь наша страница основана на сетке!
 
   Сама сетка разделена на 12 колонок по 69 пикселей каждая, отделенных друг от друга промежутками шириной в 12 пикселей (12px). В сумме колонки и промежутки дают нам полную ширину в 960px. Сам же блог шириной 900 пикселей отцентрирован по горизонтали в пределах холста.
   Вот они, детали высокого уровня. И если мы внимательно рассмотрим две колонки в блоге (рис. 2.13), то увидим, что ширина левой основной колонки (.main в нашей разметке) составляет 566 пикселей, в то время как ширина правой вспомогательной (.other) – только 331 пиксель.
 
   Рис. 2.13. Давайте-ка изучим детали и измерим ширину внутренних колонок
 
   Что-то слишком много пикселей вокруг, да? И если бы пиксели нас устраивали, мы могли бы просто перенести их в CSS. (Эй! Это очень важно!)
 
   #page {
   margin: 36px auto;
   width: 960px;
   }
 
   .blog {
   margin: 0 auto 53px;
   width: 900px;
   }
 
   .blog.main {
   float: left;
   width: 566px;
   }
 
   .blog.other {
   float: right;
   width: 331px;
   }
 
   Отлично. Мы установили ширину #page в 960 пикселей, отцентрировали в ней модуль .blog шириной 900 пикселей, задали ширину .main (566) и .other (331) и наконец-то разместили эти колонки рядом. Результат выглядит шикарно (рис. 2.14).
 
   Рис. 2.14. Мы избавились от ненужных пикселей, и наш дизайн почти готов. Или нет?
 
   И хотя наш макет идеально совпадает с оригинал-макетом, он получился совсем негибким. Фиксированная ширина в 960px делает нашу страницу совершенно безразличной к изменениям размеров области просмотра. Иными словами, если ширина окна будет меньше 1024 пикселей, перед читателем появится полоса горизонтальной прокрутки (рис. 2.15).
   И нас это, мягко говоря, не устраивает.
 
   Рис. 2.15. Дизайн выглядит отлично, но он совсем негибкий. Давайте это исправим

От пикселей к процентам

   Вместо того чтобы переносить значения в пикселях из оригинал-макета в CSS, мы должны перевести эти размеры в относительные, пропорциональные значения. В результате мы получим сетку, которая будет трансформироваться в зависимости от области просмотра, причем оригинальные пропорции дизайна останутся неизменными.
   Давайте начнем с первого элемента #page, который содержит наш макет, и попробуем что-нибудь с ним сделать:
 
   #page {
   margin: 36px auto;
   width: 960px;
   }
 
   Противные, гадкие пиксели. Терпеть их не можем!
   Ну ладно, не такие уж они и отвратительные. Помните: в макетах с фиксированной шириной нет ничего плохого! Но нам нужна более гибкая сетка, поэтому давайте попробуем перевести эти 960 пикселей в проценты.
 
   #page {
   margin: 36px auto;
   width: 90%;
   }
 
   Должен признаться, что я пришел к этим 90% без особых на то оснований, просто пробовал различные варианты в окне браузера, а затем выбрал тот, что понравился мне больше всего. Задавая значение элемента #page в процентах, мы создаем контейнер, который будет увеличиваться и уменьшаться в зависимости от области просмотра (рис. 2.16). И поскольку он отцентрирован по горизонтали, справа и слева останутся отступы по 5%.
 
   Рис. 2.16. Наш контейнер изменяется в размерах при любом изменении размера окна браузера
 
   Пока все идет неплохо. Теперь давайте примемся непосредственно за модуль .blog. Чуть ранее, когда мы играли с пикселями, то установили следующее правило:
 
   .blog {
   margin: 0 auto 53px;
   width: 900px;
   }
 
   Теперь вместо величины в пикселях мы должны выразить ширину элемента .blog в пропорциональных величинах: описать ее как процент ширины содержащего его элемента. И вот здесь нам снова пригодится формула target ÷ context = result.
   Из оригинал-макета мы знаем, что ширина нашего блога должна составлять 900px. Теперь нам нужно представить эту ширину в относительных единицах, процентах ширины родительского элемента для элемента .blog. Поскольку блок .blog вложен в элемент #page, ширина которого в соответствии с оригинал-макетом составляет 960 пикселей, это и есть наш контекст.
   Давайте разделим ширину .blog (900) на его контекст (960):
 
   900 / 960 = 0,9375
 
   У нас получилось 0,9375. Число выглядит не особенно впечатляюще. Но, передвинув запятую на два знака, мы получаем 93,75% и заносим их прямо в CSS:
 
   .blog {
   margin: 0 auto 53px;
   width: 93,75%; /* 900px / 960px */
   }
 
   (Так же как и в случае с размерами шрифтов, я записал формулу в поле комментария справа от значения ширины (width). Это, разумеется, дело вкуса, но я нахожу это очень полезным.)
   Итак, с двумя элементами мы разобрались. Но что делать с колонками?
 
   .blog.main {
   float: left;
   width: 566px;
   }
 
   .blog.other {
   float: right;
   width: 331px;
   }
 
   Ширина основной колонки, которая расположена слева, составляет 566px, ширина же левой колонки равна 331px. Эти цифры нам тоже придется перевести в проценты. Но прежде чем подставить их в формулу, обратите внимание на то, что контекст изменился. Последний раз мы делили ширину модуля .blog на 960, ширину его контейнера (#page). Но поскольку эти блоки вложены в .blog, нам нужно делить целевую ширину колонок (566 и 331) на ширину их нового контекста, то есть ширину .blog (900). В результате мы получаем:
 
   566 / 900 = 0,628888889
   331 / 900 = 0,367777778
 
   Передвинув запятую на два знака, мы получаем в итоге 62,8888889% для блока .main и 36,7777778% для блока .other:
   .blog.main {
   float: left;
   width: 62.8888889%; /* 566px / 900px */
   }
   .blog.other {
   float: right;
   width: 36.7777778%; /* 331px / 900px */
   }
 
   Вот мы и получили гибкий макет (рис. 2.17). При помощи небольших расчетов мы создали контейнер, выраженный в процентах, и две гибкие колонки, что дает нам макет, меняющий свои размеры в соответствии с размерами окна браузера. При этом ширина в пикселях тоже меняется, а пропорции дизайна остаются исходными.
 
   Рис. 2.17. Наша гибкая сетка готова

Гибкие поля и отступы

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

Не продохнуть…

   Наш дизайн уже достаточно гибок, однако он требует серьезного внимания к двум основным деталям. Название блога уехало далеко влево (рис. 2.18), а две колонки примыкают друг к другу без каких-либо отступов или промежутков (рис. 2.19). Определенно, нам нужно еще поработать.
   (Конечно, на самом деле мы без них страдаем.)
 
   Рис. 2.18. Наш заголовок отчаянно нуждается в полях
 
   Рис. 2.19. Отступы? Мы не признаем никаких отступов!
 
   Рис. 2.20. Согласно параметрам эскиза, нам нужно задать горизонтальное поле в 48 пикселей с левой стороны заголовка
 
   Ну что ж, давайте начнем с заголовка. В оригинальном макете между началом заголовка и левым краем контейнера есть промежуток в 48 пикселей (рис. 2.20). Мы, конечно, могли бы задать поле (padding-left) в пикселях или em:
 
   .lede {
   padding: 0.8em 48px;
   }
 
   Это хорошее решение. Но это фиксированное значение левого поля (padding-left) создаст промежуток, который не будет сочетаться со всей «резиновой» сеткой. И когда гибкие колонки будут становиться у́же или шире, это поле проигнорирует остальные пропорции дизайна, и ширина его всегда окажется 48 пикселей (48px), независимо от того, насколько уменьшился или увеличился весь макет.
   Так что мы не пойдем этим путем – мы создадим гибкий отступ. Пока что мы использовали относительные единицы измерения только в отношении ширины различных элементов, но мы можем это сделать и с полями и отступами. И воспользуемся для этого нашей проверенной формулой:
 
   target ÷ context = result
 
   Прежде чем мы снова займемся вычислениями, хочу обратить ваше внимание на то, что контексты для гибких полей и для гибких отступов немного отличаются.
   1. Задавая гибкие отступы для элемента, принимайте за контекст ширину контейнера элемента.
   2. Задавая гибкое поле для элемента, принимайте за контекст ширину самого элемента. Подумайте о «боксовой» модели, и эти предложения обретут смысл: мы описываем поле в отношении к ширине самого элемента.
   Поскольку мы хотим определить поле заголовка, в качестве контекста мы возьмем ширину самого элемента .lede. Ширина заголовка нам неизвестна, поэтому мы берем ширину модуля блога, то есть 900 пикселей. Снова открываем калькулятор и получаем:
 
   48 / 900 = 0,0533333333
 
   и переводим результат в:
 
   .lede {
   padding: 0.8em 5.33333333%; /* 48px / 900px */
   }
 
   Наши 48 пикселей поля теперь выражены в относительных единицах измерения, как доля ширины заголовка.
   С этим расправились, идем дальше. Давайте введем понятие пробела в наш контент. Но сначала вспомним, что каждая колонка фактически содержит меньший модуль: левая колонка .blog содержит модуль. article, а правая .other – список .recent-entries (рис. 2.21).
 
   Рис. 2.21. Взглянув на колонки, мы можем достаточно быстро определить их ширину
   
Конец бесплатного ознакомительного фрагмента