Одно из модных направлений веб-дизайна последних лет — оформление заголовков контрастным фоном. Например, вот так:
Простая, на первый взгляд, задача решается не так уж и просто: первая же мысль «добавить padding» натыкается на то, что отступ добавляется исключительно в начале и в конце текста, игнорируя переносы:
Ближе всех к решению задачи когда-то подошёл akella, добавив border
у родительского элемента. Но проблема не решена на 100%: в конце первой строки (место, где переносятся слова) всё равно нет отступа. Решения остальных ребят, которые присылались мне в твиттер, грешили одной и той же проблемой: нужно точно указать место разрыва строк.
В простейшем случае, когда нужно добавить небольшой отступ, решение оказалось до боли простым. Есть одно «паразитное» CSS-свойство, от которого кодеры обычно избавляются — это свойство outline
. Его особенность заключается в том, что во всех браузерах (по крайней мере в тех, в которых я проверял: Safari 4, Firefox 3.5, Opera 10, IE8) контур outline точно повторяет границы текстового элемента. Соответственно, эта строчка кода полностью решает нашу проблему:
span.uniform-bg { outline: red solid 0.3em; }
Не обошлось без ложки дёгтя: в данном случае «плохим мальчиком» оказался Firefox. Во-первых, он иногда рисует контур с небольшим отступом от границ текста, а во-вторых — прочерчивает его между строками, перекрывая текст:
Первая проблема решается довольно просто: достаточно немного «втянуть» контур с помощью CSS-свойства outline-offset
(либо -moz-outline-offset
, эксклюзивно для Firefox), вторая — добавлением ещё одной обёртки с position:relative
, чтобы поднять текст над контуром.
Итоговое решение выглядит так:
<style type="text/css"> .uniform-bg { background:red; position:relative; outline: red solid 0.3em; -moz-outline-offset:-0.04em; } .uniform-bg span { position:relative; } </style> <h2><span class="uniform-bg"><span>Hello everyone</span></span></h2>
Оно не работает в IE6—7, в них не поддерживается свойство outline
. Но, так как это исключительно декоративная задача, можно объединить её с решением от akella и получить почти идеальное решение.
UPD: читатель Roman указал на баг в отрисовке фона в месте переноса строк в IE6—7. Немножко доработать напильником — и получится вполне приличное решение (обновил пример).
Лично меня такой способ полностью не устраивает, так как есть ограничения на высоту строки (при больших значениях появляются проблемы между строками) и толщину контура (слишком толстый контур выглядит очень некрасиво). Предлагаю читателям подумать вместе со мной над более гибким решением, а также — совсем крутота — как такое же провернуть с фоном-картинкой.
Второй способ (upd)
Тот же читатель Roman предложил ещё один способ решения задачи. Он основан на смещении трех слоёв относительно друг друга: например, если отступ равен x
, то второй слой смещается на 2x
вправо, а третий на –x
, влево:
Его можно немного упростить, убрав один слой и добавив левый border
у контейнера. Способ более гибкий, чем с outline
(который, как выяснилось, не очень дружит с Opera). На основе него я хотел сделать решение с фоновой картинкой, но столкнулся проблемой: вместе с переносом строк переносится и фон, то есть во второй строке фон начинается там же, где заканчивается в первой: