Посты с тэгом «outline»

  • Равномерный фон под текстом

    Одно из модных направлений веб-дизайна последних лет — оформление заголовков контрастным фоном. Например, вот так:

    example

    Простая, на первый взгляд, задача решается не так уж и просто: первая же мысль «добавить padding» натыкается на то, что отступ добавляется исключительно в начале и в конце текста, игнорируя переносы:

    padding

    Ближе всех к решению задачи когда-то подошёл akella, добавив border у родительского элемента. Но проблема не решена на 100%: в конце первой строки (место, где переносятся слова) всё равно нет отступа. Решения остальных ребят, которые присылались мне в твиттер, грешили одной и той же проблемой: нужно точно указать место разрыва строк.

    В простейшем случае, когда нужно добавить небольшой отступ, решение оказалось до боли простым. Есть одно «паразитное» CSS-свойство, от которого кодеры обычно избавляются — это свойство outline. Его особенность заключается в том, что во всех браузерах (по крайней мере в тех, в которых я проверял: Safari 4, Firefox 3.5, Opera 10, IE8) контур outline точно повторяет границы текстового элемента. Соответственно, эта строчка кода полностью решает нашу проблему:

    span.uniform-bg {
    	outline: red solid 0.3em;
    }
    

    Не обошлось без ложки дёгтя: в данном случае «плохим мальчиком» оказался Firefox. Во-первых, он иногда рисует контур с небольшим отступом от границ текста, а во-вторых — прочерчивает его между строками, перекрывая текст:

    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, влево:

    method2

    Его можно немного упростить, убрав один слой и добавив левый border у контейнера. Способ более гибкий, чем с outline (который, как выяснилось, не очень дружит с Opera). На основе него я хотел сделать решение с фоновой картинкой, но столкнулся проблемой: вместе с переносом строк переносится и фон, то есть во второй строке фон начинается там же, где заканчивается в первой:

    bg-problem

    Метки: , , ,