Архив за Июнь 2009

  • Религиозные войны

    Не ожидал, что статья про верстку двух колонок одинаковой высоты вызовет целый холивар на Хабре. В комментариях дискуссия велась по двум вопросам: зачем вообще нужно так извращаться и почему верстать таблицами — дурной тон. Если с первым вопросом более-менее разобрались (правдивые комментарии оставили errr, Jenek и ArtyV), со вторым вопросом все довольно грустно. Одни кричат, что таблицы для нетабличных данных — не семантично и не круто, вторые — что таблицами все делается проще и быстрее. И те, и другие в корне не правы.

    Верстка сайта, как и дизайн, это решение поставленной задачи, а не очередной способ понтануться перед коллегами-гиками или схалявить. Я еще ни разу не получал задания «написать html-код», но постоянно получаю «сделать сайт», а это — не одно и то же. Сайт — это живой механизм со своим внутренним миром, своими проблемами и планами на будущее. От того, как вы его спроектируете, зависит то, рассыпется ли он при малейшем дуновении ветра или выдержит удар ядерной боеголовки (дружно вспоминаем сказку про трех поросят).

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

    С семантикой тоже не все замечательно. Я не отрицаю, что это здорово и правильно, но вот скажите, если ли официальная спецификация семантичной верстки? Или же все это — частное мнение отдельных личностей, которое разнится от человека к человеку? Как, например, мне сверстать шахматную доску, чтобы любой user agent понял, что это именно шахматная доска, а не бессмысленное нагромождение элементов?

    Семантичность того или иного решения в первую очередь должна определятся решаемой задачей, а не частным мнением людей со стороны. Вот типичный пример, на котором я ловлю большинство идеологов семантичной верстки. Как у любого ИТ-специалиста, у этих ребят в своих блогах есть листинги кода. И этот листинг обычно сопровождается нумерацией строк, что очень даже удобно при описании принципов работы кода. И как же эти листинги оформляются? Правильно, через <ol>/<li> конструкции. Семантично? — вроде да. А я считаю, что нет. Нумерация — это декоративная составляющая листинга, которая никак не связана с самим кодом. А с помощью <ol>/<li> нумерация вдруг стала смысловой составляющей. Что выливается в то, что 95% пользователей при попытке скопировать этот код или его часть получат нумерацию строк впридачу. А ведь этот код вывешивается именно с целью дать посетителю скопировать и опробовать его. Нарушение семантики налицо. Некоторые, конечно, догадываются об этой проблеме, но решают они ее не отдельной колонкой с нумерацией, а кнопкой «view plain». То есть пользователю предлагается потанцевать с бубном только ради того, чтобы скопировать текст.

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

  • Кат или не кат?

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

    RSS, естественно, это не касается.

    UPD: Чтобы ответить на вопрос «нужен кат или нет?» надо, в первую очередь, понять, в чем проблема не-ката. Сейчас основная сложность в том, что статьи большие и относительно сложно добраться до начала очередного поста, просто прокручивая страницу. С объемом страницы проблем нет: сейчас в gzip-е она весит 17 КБ, загружается постепенно, так как все на блоках.

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

  • Две float-колонки одинаковой высоты

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

    Правильный способ

    Наиболее правильным на сегодняшний день способом верстки многоколоночных макетов является использование CSS-свойства display: table-*, например, вот так:

    <div style="display:table-cell;width:50%">
    	<div style="display:table-row">
    		<div style="display:table-cell;background:red">column 1</div>
    		<div style="display:table-cell;background:blue">column 2</div>
    	</div>
    </div>
    

    Проблема в том, что это не работает в IE6/7, которые составляют значительную долю рынка браузеров. Что ж, придется воспользоваться альтернативным способом.

    Альтернативный способ

    Как обычно, сначала разберем проблему на составляющие. Предположим, у нас есть двухколоночный макет, первая колонка шириной 25% от контейнера, а вторая — 50%:

    col1

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

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

    col2

    Какие свойства есть у float-блоков? Они находятся в потоке, значит, могут влиять на высоту контейнера. То есть если мы обрамим блоки контейнером и создадим у него правильный контекст форматирования (либо через clear-элемент, либо через overflow: hidden), наш контейнер примет высоту наибольшей колонки:

    col3

    А если мы добавим не один, а два контейнера, то оба они будут высотой с наибольший блок:

    col4

    Обращаем внимание на размеры колонок: первая 25%, вторая 50%. То есть вторая колонка ровно в 2 раза больше первой. Соответственно, если первому — внешнему — контейнеру мы задаим ширину в 25%, а второму — внутреннему — 200% (две ширины внешнего контейнера, что будет соответствовать 50% относительной всей страницы) и сместим его на ширину контейнера вправо, мы получим подобие того, чего хотим добиться:

    col5

    Осталось разобраться с текстовыми колонками. У нас появился новый контейнер, от которого рассчитываются размеры колонок. Так как левая колонка должна быть шириной в 25% от страницы, а ширина внутреннего контейнера равна 50% от страницы, то новая ширина колонки будет равна 50% (50% × 0.5 = 25%). Сама колонка не должна влиять на ширину, но все еще должна быть в потоке, поэтому подавляем влияние ширины колонки на поток с помощью margin-right:-100%, а сам элемент смещаем влево на половину ширины контейнера, то есть на 50%. Получаем именно то, что нам нужно:

    col6

    А вот сам HTML-код, с помощью которого реализуется эта конструкция:

    <style type="text/css">
    	.col-wrap1 {
    		width:25%;
    		background:blue;
    	}
    
    	.col-wrap2 {
    		width:200%;
    		margin-right:-100%; /* чтобы IE6 не раздвигал контейнер */
    		position:relative;
    		left: 100%;
    		background:red;
    	}
    
    	.col1 {
    		float:left;
    		width:50%;
    		margin-right:-100%;
    		position:relative;
    		left:-50%;
    	}
    
    	.clear {
    		clear:both;
    		font-size:0;
    		overflow:hidden; /* тройной презерватив для IE */
    	}
    </style>
    <div class="col-wrap1">
    	<div class="col-wrap2">
    		<div class="col1">left column</div>
    		<div class="col2">center column</div>
    		<div class="clear"></div>
    	</div>
    </div>
    

    Резюмируя все вышесказанное: я создал два контейнера, который являются дублерами основных колонок, и раздвигаются по высоте этими самыми колонками. Остается добавить, что этот способ является более гибким, чем использование CSS-свойств display: table-*, потому что сами колонки можно перемещать с помощью свойств top и left. Чтобы продемонстрировать потенциал этого решения, я сделал специальный пример. Обратите внимание, что у каждой колонки есть свой бордюр и фоновая картинка, выровненная по правому нижнему краю, что в принципе не возможно в других известных способах.

    На основе этого способа можно создать и больше растягивающихся колонок одинаковой высоты. Пример: сайт ВТБ24. Там три колонки одинаковой высоты; верстка осложняется тем, что первые две колонки должны быть в общей рамке, между которыми есть вертикальный разделитель. Когда я готовился к одному из мастер-классов, в одной книге про «качественную верстку» (естественно, западного автора), я прочил, что такое реализовать невозможно :) Для меня это стало очередным подтверждением, что там не умеют верстать качественные растягивающиеся сайты.

    Два слова о верстке макетов

    На первый взгляд может показаться, что этот способ слишком специфический и подходит далеко не для каждого макета. Это не так. Основной трюк заключается в том, чтобы правильно определить модульную сетку и ширину колонок и контейнеров. Пока дизайнеры не слышат, признаюсь: первое, что я делаю при верстке макета — удаляю гайды, которые нарисовал дизайнер. Они мне нужны лишь для того, чтобы понять, как должны выравниваться блоки, саму модульную сетку я делаю на основе тщательного анализа макетов (на это может уйти целый рабочий день). После этого 7 колонок превращаются в 2 контейнера-дублера с 2…4 колонками в каждом. Может, потом подробнее опишу этот момент, пока могу дать общий совет, старайтесь подбирать такие ширины контейнеров и колонок, чтобы они делили 100 без остатка, а именно: 50%, 25%, 20%, 10%, 5%, 2%, 1%. Тогда вы сможете без особых хлопот выравнивать блоки по горизонтали в вертикали в независимых контейнерах.

    Метки: , , ,
  • Пакетная оптимизация PNG

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

    optipng -o5 *.png

    Создают даже целые сервисы вроде smush.it.

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

    Что бы не говорили злые языки, но доля IE6 на рынке все еще слишком велика, чтобы сбрасывать его со счетов. Именно у этого браузера больше всего проблем с отображением разных вариаций PNG. В частности, полноцветный полупрозрачный PNG (PNG24 в терминологии фотошопа) он просто так не покажет, нужно использовать фильтр AlphaImageLoader или VML. А у полупрозрачных индексированных PNG покажет только непрозрачные пиксели. Из этого следует вывод, что нужно контролировать оптимизацию каждого файла.

    Рассмотрим несколько примеров. Для начала возьмем полупрозрачную плашку:

    …и вызовем на ней OptiPNG:

    optipng -o5 mate.png

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

    optipng -o5 -nc mate.png

    Рассмотрим второй пример:

    При попытке оптимизировать этот файл OptiPNG преобразует изображение в 8-битную палитру, однако это будет не оптимальный способ хранения изображения и вы увидите сообщение, что файл уже оптимизирован. Но я готов пожертвовать «гладкими» краями в IE6, лишь бы не извращаться с фильтрами и VML, потому что этот файл будет использоваться 50 раз на странице. Кто не в курсе: AlphaImageLoader жрет очень много памяти и процессорного времени, VML менее требователен, но все равно больше, чем обычная картинка или фон. Поэтому в данном случае нужно форсировать преобразование палитры:

    optipng -o5 -force corner.png

    Еще одним плюсом ручной оптимизации для меня является соответствие моих ожиданий действительности. Очень часто при сохранении черно-белых PNG я забывают выставить им режим цветовой Grayscale, а лог OptiPNG постоянно мне об этом напоминает, когда процент сжатия меньше 20. Кстати, smush.it не умеет преобразовывать цветовую палитру в черно-белую.

  • Firefox: редактируем textarea во внешнем редакторе

    Наконец-то добрались руки до поля поиска расширений для Firefox. Хотелось найти что-нибудь такое, что позволит редактировать содержимое полей во внешнем редакторе, а то уже запарился в CMS голый текст писать. Первый же запрос вывел на замечательный плагин It’s All Text!, который как раз делает то, что нужно. Этот плагин добавляет кнопочку edit в правом нижнем углу у <textarea>, позволяя открыть и редактировать содержимое поля в любимом редакторе.

    Пользователям Mac OS придется немного поплясать с бубном: Firefox не позволяет открыть app-бандлы напрямую. Для этого нужно написать небольшой скрипт. Создайте файл, например edit_in_coda.app (расширение обязательно app, иначе плагин не позволит выбрать скрипт) и написать там следующее:

    #!/bin/sh
    open -a Coda "$@"
    

    Затем в консоли нужно выставить этому файлу права на исполнение:

    chmod +x edit_in_coda.app
    

    Теперь вот правлю текст в Coda Espresso (там гораздо удобнее), в котором через Zen Coding можно быстро писать XML/HTML. Красота!

    Метки: ,

← cтарое