-
Равномерный фон под текстом
Одно из модных направлений веб-дизайна последних лет — оформление заголовков контрастным фоном. Например, вот так:
Простая, на первый взгляд, задача решается не так уж и просто: первая же мысль «добавить 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). На основе него я хотел сделать решение с фоновой картинкой, но столкнулся проблемой: вместе с переносом строк переносится и фон, то есть во второй строке фон начинается там же, где заканчивается в первой:
37 комментариев
Надо взять на заметку
в словосочетании ничего нельзя вставлять? 🙂
и да в ФФ3.6рц2 бока есть
http://deer.org.ua/filez/ff36rc2.png
В смысле? Можно задать любой текст и любую ширину контейнера, всё будет как надо. А бока можно ещё больше подтянуть.
та я имел ввиду доп-спаны (другие тэги) внутри текста, но понял что не нужно 😉
А чем не устраивает блочный элемент + float?
>>А чем не устраивает блочный элемент + float?
Тем, что это не работает )
Первое что пришло в голову — добавить неразывный пробел после hello и перед everyone.
Но это очень кривой костыль.
Чем мне не нравится outline — в той же Опере он тормозит прокрутку страниц.
egorinsk, мне из-за этого именно опера не нравится 🙂
Андрей, ну вообще да, у нее есть еще веселые баги с не-обновлением картинки на экране при изменениях в DOM, например когда от выезжающего меню куски нестертые остаются. Сколько сил убито на его лечение, ужас. Естественно, при этом разные версии еще и ведут себя (=глючат) по разному.
Но с точки зрения пользователя, а не верстальщика — она мне очень даже нравится 🙂
Есть довольно тяжеловесное универсальное решение, но оно слишком тяяяяжелое!
Там 1 и тот же текст повторяется 3 раза, в 2х случаях он спрятан и спозиционирован под основным блоком с отступами слева и справа. Но там можно подкладывать любой фон, менять расстояния между строками и работает везде.
Но опять таки слишком много элементов и повторение текста плохо сказывается на seo.
Если кто подскажет универсальное решение, с 1 блоком то ему огромное спасибо за это 🙂
Ещё outline покалечили в Opera 9.5, сделав его инструментом веб-разработчика: обводку теперь нельзя перекрыть ничем (даже IFRAME 🙂
http://rusrestaurant.com/tests/opera-bugs/opera95-css-bug-outline.html
Вместо -moz-outline-offset:-0.04em можно поставить .uniform-bg span { background:red; }.
А как вам такое решение (пока кроме IE 5-7)?
http://korb.ru/temp/
Высота строки компенсируется паддингом.
Roman, очень хорошо. Обновил статью.
Фон кратным line-height не лечится? (в общем, не панацея, конечно)
Так фон можно фиксированным сделать, а для IE экспрешин. Такая полосатая заливка будет очень эффектно выглядеть с фиксированным фоном.
Фон кстати можно вылечить простым background-attachment:fixed;
Вот только опять же про IE промолчим…
Прокрутка текста с
background-attachment: fixed;
определённо доставляет 🙂Наркотики не твоя тема ;)))
зы: мой єксперимент http://deer.org.ua/2010/01/21/1/
Для многих, лучшим решением будет ручное разбиение фразы на строки при помощи span-ов c padding-ом. Самый психически здоровый способ, при условии, что текст не часто меняется и т.д.
uggallery, а чем способ от Романа тяжелее «психически здорового» выделения каждого слова span’ом?
поместив в текст ссылку мы увидим, что в хроме пропадают подчеркивания текста. а если переместить ссылку под span, ie делает блок текста ровно прямоугольным.
сижу, борюсь с хромом 🙂
По мне дак лучше заголовки вообще с прозрачным фоном делать. Так приятнее и удобнее.
Sorry, I don’t speak Russian, but here is my rough translation:
Жаль, я не говорю на русском языке, но вот — мой грубый перевод:
Эта статья заинтриговала меня, чтобы создать более чистое решение.
В то время как мое решение воздействует на все браузеры, Вы действительно должны приспособить второстепенное положение, таким образом это измеряет должным образом.
Решения — полностью CSS, базируемый, и используют редко используемый признак с абсолютным расположением. Это учитывает вершину или практический результат, чтобы быть любой шириной, не нарушая расположение.
Кроме того, высота заголовка включена, так типографский поток последователен.
Вы можете рассмотреть мой демонстрационный пример здесь:
http: // http://www.bryanwatson.ca/Misc/Block-Heading.html
Bryan, there are two problems with your solution:
Very true, my solution was mainly to demonstrate that it can look uniform across all browsers.
Currently, without using some one-off javascript, there is no perfect solution to this issue.
When used in a practical application, you have to consider what’s more important for your specific project: Presentation or Accessibility
If accessibility is more important then presentation, then using any of the techniques listed probably wouldn’t be a wise choice in the first place.
When considering using semantic, clean code for purely presentation purposes, then my solution fits that need.
Насчет последнего метода — «его можно немного упростить, убрав один слой и добавив левый border у контейнера». Так вот, это дело начинает бажить в IE8, хотя в остальны все отлично 🙁
как выяснилось, если для основного контейнера не указать left,отличный от 0, то начинаются баги в IE8. Почему — черт его знает. Для IE 6-7 оптимально выдавать вариант с border слева. Проверил в IE6-7-8, Opera 9-10, FF 2-3, Safari 3-4 — работает.
пример тут: http://vlad.flango.ru/fon-span/
Начиная с FF 3.6 (Gecko 1.9.2) свойство moz-outline-offset больше не поддерживается, поэтому заменяем:
.uniform-bg {
background:red;
position:relative;
outline: red solid 0.3em;
-moz-outline-offset:-0.04em;
}
на
.uniform-bg {
background:red;
position:relative;
outline: red solid 0.3em;
}
@-moz-document url-prefix() {.uniform-bg {outline-offset:-0.04em;}}
Второе решение тоже не идеальное:
http://igorfrolov.info/s/i/temp/heading_outline.png
Перехлёст выносных элементов — такое точно не устроит ни одного дизайнера.
Так или иначе варианты выглядят вполне не плохо. Сейчас бьюсь с проблемой :hover в варианте с графической подложкой.
> как выяснилось, если для основного контейнера не указать left,отличный от 0, то начинаются баги в IE8. Почему — черт его знает. Для > IE 6-7 оптимально выдавать вариант с border слева. Проверил в IE6-7-8, Opera 9-10, FF 2-3, Safari 3-4 — работает.
> пример тут: http://vlad.flango.ru/fon-span/
по-моему хорошее решение, спасибо vlad43 🙂
А как быть, если фон полупрозрачный?Если в примере поменять красный на скажем rgba(1,0,0,0.5), то появляются уродливые горизонтальные полосы из-за наложения полупрозрачности.
Если размер шрифта, то нижняя строка наезжает на верхнюю. Как можно побороть ?
меньше 1.2