• Универсальный способ декорирования блоков

    В прошлой домашке я предложил читателям придумать способ вёрстки блоков со скругленными уголками и тенью. Если посмотреть на решения, то увидите, что большинство из них очень похожи друг на друга: 4 элемента, разбросанных по углам, одинаково «необычный» вид картинки, небольшие различия в наложении блоков. Давайте рассмотрим подробнее, за счет чего работают эти способы, а также почему эта статья не называется «Создание скруглённых блоков с тенью».

    Начать, в первую очередь, стоит с определения проблемы, которую нужно решить. Предположим, у нас есть блок со скруглёнными уголками и тенью:

    1

    Внутри блока есть контент неопределенной ширины и высоты, тень полупрозрачная; сам блок может иметь как заданную ширину (пиксели, проценты), так и автоматическую (width: auto). Наша задача: найти наиболее оптимальный способ вёрстки подобных блоков. Под оптимальностью я подразумеваю наименьшее количество элементов, наименьшее количество графических файлов, работа во всех современных браузерах, минимальное количество правок под конкретный браузер. Все эти принципы так или иначе влияют на производительность и надёжность нашего решения, особенно на крупных проектах.

    Справедливости ради стоит отметить, что мы будем рассматривать неопределенность габаритов контента в каком-то определенном диапазоне, например, 1000×1000 пикселей. То есть я буду рассказывать про какие-то небольшие контекстные всплывающие блоки, которыми сейчас переполнены различные сайты. Если вам нужно будет, например, сделать тень у блока, в котором содержится основной контент сайта, то лучше выбрать другой способ.

    Простой способ

    Если присмотреться внимательно на пример выше, то можно сразу же найти простое и оптимальное решение: мы разделим наши декорации на 4 зоны, в каждой из которых покажем определенный фрагмент одной фоновой картинки:

    2

    • Первая область: растягивается по горизонтали и вертикали, background-position: top left;
    • Вторая область: ширина фиксированная, растягивается по вертикали, background-position: top right;
    • Третья область: растягивается по горизонтали, высота фиксированная, background-position: bottom left;
    • Четвертая область: ширина и высота фиксированная, background-position: bottom right.

    Реализовать такую конструкцию — проще простого, но есть один нюанс: блоки должны растягиваться не на всю ширину контейнера, а на ширину контейнера минус ширина бокового блока (в данном случае это 2 и 4). То же самое касается высоты. Решается эта задача довольно просто. Не каждый знает, что задавать размеры блокам можно не только с помощью CSS-свойств width и height , но и с помощью комбинаций left/right и top/bottom у абсолютно спозиционированных элементов. Примерный код может выглядеть так:

    <style type="text/css">
    	.shadowed {
    		position: relative;
    		left: 200px;
    		top:  100px;
    		padding: 10px;
    		width: 30%;
    		max-width: 450px;
    	}
    
    	.sh {
    		position: absolute;
    		background: url(./shadow.png) no-repeat;
    		z-index: -1;
    	}
    
    	.tl {
    		/* задаем высоту */
    		top: -6px;
    		bottom: 12px;
    
    		/* задаем ширину */
    		left: -11px;
    		right: 14px;
    	}
    
    	.tr {
    		width: 25px;
    		top: -6px;
    		bottom: 12px;
    		right: -11px;
    		background-position: top right;
    	}
    
    	.bl {
    		left: -11px;
    		right: 14px;
    		bottom: -16px;
    		height: 28px;
    		background-position: bottom left;
    	}
    
    	.br {
    		width: 25px;
    		height: 28px;
    		right: -11px;
    		bottom: -16px;
    		background-position: bottom right;
    	}
    </style>
    <div class="shadowed">
    	Hello world
    	<div class="sh tl"></div>
    	<div class="sh tr"></div>
    	<div class="sh bl"></div>
    	<div class="sh br"></div>
    </div>
    

    Если вы откроете пример в любом современном браузере, то увидите, что всё работает замечательно. Но ребята из Редмонда не могли пройти мимо такой халявы и решили усложнить нам жизнь своим продуктом под названием Internet Explorer 6, в котором:

    • не работает растягивание с помощью top/bottom и left/right;
    • свойства bottom и right работают не правильно (позиция элемента отсчитывается от чётной ширины/высоты контейнера);
    • полупрозрачный PNG нельзя наложить и позиционировать как обычный фон.

    В принципе, все эти проблемы легко решаются с помощью expressions и DD_belatedPNG, однако это слишком тяжеловесное решение для старичка IE6, особенно если таких блоков у вас будет несколько на странице. Попробуем найти другое решение этих проблем, заодно разомнём мозг.

    Растягивание по горизонтали

    Начнем с того, что придумаем другой способ растягивания блока по горизонтали. Попробуем задать первому блоку ширину в 100%. Получим вполне ожидаемый результат: блок растягивается на всю ширину контейнера.

    3

    Если же этот блок сместить влево на ширину декорации справа, то мы как раз освободим место для блока номер 2. А если родителю указать overflow: hidden, то выпирающий слева кусок первого блока не будет виден. Это именно то, что нам нужно: при растягивании контейнера оба блока будут занимать всю доступную ширину и нормально стыковаться друг с другом:

    4

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

    5

    Решить эту проблему, опять же, довольно просто: обрамим первый и второй блок еще одним блоком, которому выставим width:100%; overflow: hidden и верхний и боковые паддинги по размеру тени. Так как мы задали ширину, то боковые паддинги увеличат размер блока до нужных значений и наша тень будет полностью отображаться. А overflow: hidden с основного контейнера можно убрать, и это даст нам дополнительное преимущество: мы сможем разместить внутренний элемент за границами контейнера (например, кнопку закрытия).

    Добавив padding у внутреннего контейнера, мы столкнёмся с тем, что первый блок будет меньшего размера, чем нам нужно. Но, опять же, так как у него задана ширина, мы можем «добить» ширину до нужного значения с помощью свойства padding-right:

    4_2

    Картинка

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

    sprite-sample

    Правая декорация у первого блока будет скрыта overflow:hidden контейнера, а ширина второго блока равна ширине правой декорации и покажет только её. А если перенести вверх еще и нижнюю часть, то мы сможем наложить один и тот же спрайт на все 4 блока:

    sprite2

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

    Расположение блоков справа и снизу

    Как я уже отметил, в IE6 неправильно работают CSS-свойства right и bottom, и для нас это проблема, так как мы имеем дело с полупрозрачными элементами. Любая нестыковка блоков даже в 1 пиксель будет сразу бросаться в глаза.

    Свойство right исправить очень просто: достаточно вместо него воспользоваться margin-left:100% — это разместит блок ровно у правого края, а с помощью left можно подтянуть блок в нужное место. С bottom немного сложнее: я не знаю альтернативных путей, кроме как позволить самому контенту опустить этот блок до нужного уровня. На предыдущем шаге мы добавили обёртку с двумя блоками внутри, туда же мы добавим и контент. Под обёрткой разместим наши нижние блоки.

    Эта обёртка и будет определять, на какой высоте окажутся блоки 3 и 4. Согласно спецификации CSS, элемент с position: absolute, у которого не указаны позиционирующие свойства — top/right/bottom/left — должен размещаться в том месте потока документа, где размещался бы статический элемент. Это очень удобно, так как благодаря этому можно делать различные трюки в виде выносных блоков, привязанных к определённому слову в тексте (например, смотрите выноску про Hyatt Hotel на сайте Башни Федерации).

    У этой обёртки задан overflow: hidden, который выполняет 2 функции: скрывает ненужные куски внутренних декоративных блоков и задает контекст форматирования. Это значит, что никакие марджины внутри не будут выпирать наружу, что гарантирует нам точную позицию нижних блоков.

    Нижние блоки

    Если помните, мы убрали overflow: hidden у самого контейнера. Поэтому, чтобы растянуть блоки 3, 4 так же, как и 1, 2, нам, похоже, придется добавить еще одну обёртку. Однако есть одно CSS-свойство, о котором кодеры часто забывают — это свойство clip. С помощью него мы и скроем выпирающий левый край.

    Результат

    Надеюсь, вы поняли саму идею, за счет чего работает большинство решений, присланных пользователями. Кратко подведу итог: для верстки декорированных блоков понадобится 5 элементов и одна картинка. Элементы располагаются следующим образом: одна обёртка, в которой находятся левый верхний и правый верхний углы, а также контент. У этой обёртки выставлен overflow: hidden, который скрывает выпирающие части у декоративных блоков, а также задает контекст форматирования. Эта же обёртка определяет позицию двух нижних блоков по вертикали. Выпирающая левая часть у левого нижнего блока отрезана с помощью clip. Спрайт мы подогнали таким образом, чтобы нам не нужно было указывать background-position, который всё равно не сработает в IE6, так как там мы воспользуемся фильтрами. В этом спрайте мы как бы вывернули блок наизнанку, переместив нижнюю часть вверх, а правую — влево.

    А вот и моё решение. Как видно из примера, решение полностью кроссбраузерное, для IE6 понадобилось всего лишь добавить padding у некоторых блоков (это можно сделать и с помощью одноразового expression).

    С помощью этого способа можно декорировать любой блок, где надо равномерно покрыть все 4 стороны. Например, можно плоскую и скучную обложку книги превратить в объёмную, как это сделано на сайте Аймобилко (правда, там используется немного другой способ из-за технических особенностей сайта):

    imobilco

    Единственный минус этого способа — сложность расчета паддингов у элементов: где-то нужно брать размер всей декорации, где-то только её часть. Но все эти расчеты очень легко алгоритмизируются, как бы намекая на то, что можно сделать удобный онлайн-сервис для быстрого создания декораций.

    Метки: , , ,
  • 75 комментариев

    1. odiszapc
      20 октября 2009

      Сергей вы как всегда красавец. Спасибо за намек по книгам.

    2. 20 октября 2009

      мда… читаю ваши заметки и всё больше убеждаюсь, что веб становится всё уродливее изнутри и неповоротливей снаружи. Странные и изжившие себя стандарты с каждым годом усложняют жизнь тысячам(? может миллионам?) людей, а про рендеринг страниц в стиле «кто как хочет, так и дрочит» среди браузеров — я вообще молчу. И разработчики покорно молчат «ну да, ну не удобно, ну не совместимо, да отказываемся от многого, да тратим время и траффик на избыточны фичи». И вот чтобы сделать такую элементарную фишку как расписно выше — нужно изъеб….ся так, что всё желание разрабатывать сайт отвалится. А тут мало того что новые браузеры не совместимы, так ещё и некромантией надо заниматься для ie6… Тот же HTML5, который всё никак не разродится, тоже не будет решением. Да, он облегчит многое, но опять же не будет панацеей и каждый браузер будет показывать страницы как истинный художник-посмодернист «ниипёт — я так вижу мир, отстаньте от меня». В общем html5 это реактивный двигатель на Запорожце. Неужели нет силы в мире, которая перечеркнёт html на корню и создаст новый, компактный, модульный, расширяемый, быстрый стандарт для вебстраниц и напишет под него клиент с открытым исходным кодом, который станет референсным де-факто? И при этом напишет так, что любое отклонение от стандарта полностью делает страницу неотображаемой, дабы надавать сразу любым корявым рукам? Неужели этого никто не видит и надо раздувать и без того избыточный html код адскими конструкциями для совместимости с некробраузерами? Человек же животное такое — пока не ткнёшь носом «вот новый стандарт — остальное забудь», то будет и на 95й винде сидеть… Еж птица гордая — не пнёшь, не полетит. Так и тут. 🙂 Доколе это будет продолжаться???? Ведь страдают как юзеры, так и разработчики.

    3. Сергей Чикуенок
      20 октября 2009

      Лично я проблем в самом HTML/CSS не вижу. Да, отчасти они избыточны, но они очень гибкие в реализации различных сложных интерфейсов. За удобство HTML/CSS говорит еще и то, что многие вендоры сейчас добавляют поддержку веб-стандартов для кастомизации своих продуктов. Например, новый Eclipse — e4 — можно будет расширять с помощью JavaScript, а внешним видом управлять через CSS. Для айфона гораздо проще, быстрее и дешевле сделать интерфейс программы на WebKit (то есть с помощью HTML/CSS/JS), чем через официальный Interface Builder.

      А проблема кроется в программах, которые пытаются весь этот код понять (читай, веб-браузеры). И насчет раздувания HTML5 новыми элементами согласен — в этом плане я полностью на стороне Microsoft, который недавно подключился к разработке стандарта и раскритиковал его за обилие неоднозначных элементов. Если бы в мире остался один только WebKit — счастью моему не было бы предела 🙂

      Но есть и обратная сторона: человек, который умеет делать грамотные и простые решения для разных браузеров, всегда сможет требовать больше денег за свои услуги 🙂

    4. 20 октября 2009

      Кстати, раз уж такая пьянка, то было бы интересно посмотреть на вёрстку типичный балунов для Яндекс или Гугл.Карт. Я когда-то верстал балуны для Яндекса, но использовал там таблицы, поскольку бестабличное решение сильно бажило и было слишком напичкано expression’ами.

      Главное условие — увеличение по содежимому от пимпочки (одна буква, одна строка) до целого блока (картинка, много текста), тень в спрайте, а центр позиционирования в правом нижнем углу.

    5. 20 октября 2009

      В условии к домашнему заданию пишете: «…Итак, хороший способ должен работать во всех современных браузерах, включая IE6».

      Теперь: «Если вы откроете пример в любом современном браузере, то увидите, что всё работает замечательно. Но ребята из Редмонда не могли пройти мимо такой халявы и решили усложнить нам жизнь своим продуктом под названием Internet Explorer 6».

      То ли это такая терминологическая избирательность, то ли 6-й ИЕ перестал быть современным браузером где-то между 7-м и 20-м октября, то ли я чего-то не понимаю.

    6. Сергей Чикуенок
      20 октября 2009

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

      bes island: вообще, IE6 я не отношу к современным браузерам. Наверно, правильнее было бы написать «…хороший способ должен работать во всех современных браузерах, а также в IE6».

    7. 20 октября 2009

      Сергей, вот пример: http://maps.yandex.ru/. Заходишь, тыкаешь на кнопку «Добавить метку» (вторая справа в ряду кнопок на карте), потом тыкаешь на карту и видишь балун.

      Кстати, забыл дать ссылку на свой вариант решения задачи в стиле «а вот как это должно работать на самом деле» — http://pepelsbey.net/pro/misc/border-image/

    8. Сергей Чикуенок
      20 октября 2009

      Вызов принимаю, уже думаю над решением 🙂

    9. Anton Poleshchuk
      20 октября 2009

      хорошее решение, спасибо!
      про clip, к своему стыду, действительно не знал

    10. GreLI
      20 октября 2009

      pepelsbey, по содержимому это как раз мой пример из последней домашки.

    11. Сергей Чикуенок
      20 октября 2009

      GreLI: всё не так просто, есть нюансы именно в позиционировании блока в нужной точке.

    12. 20 октября 2009

      Сергей, то что Вы привели примеры типа эклипса это только подтверждает мои мысли 🙂 Эклипс — прекрасный пример стандартизированной платформы, которая сама в себе и применение html+js в её рамках будет стандартом, который вполне обоснован. Извращаться в её пределах, как веб-девелоперы с браузерами, никто не станет: написал html елемент и он однозначно работает в рамках платформы без выкрутасов. Вот этого и не хватает в вебе, который как бы сам по себе масштабная платформа, но почему-то каждый дрочит… ну вы в курсе 🙂 Чтобы прояснить свою мысль представьте что VisualStudio введёт такую же поддержку html+js у себя и объявит совместимость с эклипсом (о боже!)? И вот тут начнётся ужас, когда разработчик расширения захочет малой кровью сделать плагин и для эклипса и для vs… Это то, что щас в вебе и творится — нет однозначности в реализации при вполне полной однозначности стандартов. И я думаю, что вы должны согласиться — html это язык разметки текста, а не фундамент для UI, RIA и ajax. Покажите мне хоть одного разработчика, который для создания UI и логики в своём софте будет всё лепить в ворде? Правда же нонсенс? Не, ну конечно оно-то можно… но каков результат будет? 🙂 То же и с html — слепить-то можно, но какой ценой и затратами 🙂 Про остальные платформы я так же думаю — пока платформа сама в себе и имеет свои стандарты, то в её рамках допустимы любые извращения html/css, но в рамках целой всемирной инфраструктуры такой бардак — это кошмар. 🙂 И кстати все они юзают html+css только потому, что альтернативы попросту нет 🙂

      И тот же CSS более удобнее описывается sass на мой взгляд. Кстати для чего создавались различные фреймворки тима extjs? Xтобы отделить разработчика от трахания с неоднозначностью интрепретирования вебстандартов. B d частности я говорю о новом IBM-ском EGL (не вникал в него, но суть уловил). Значит необходимость всё же есть уйти от обычного html+js? В том же html, к примеру, я попросту ненавижу закрывающие теги. 🙂 нафига они такие избыточные? сколько терабайт по миру можно было бы съэкономить если бы в сайтах не было миллиардов ? Это к вопросу о том, что почему-то JS выглядит не так: , а гараздо лаконичнее function() {} 🙂 Нафига была эта избыточность? 🙂

      Если бы вебкит был де-факто, то мир развивался бы иначе. 🙂 уже в 2000м были бы полноценные RIA c интегрированными svg, canvas и 3d (последнее кстати только в последних сборках вебкита есть уже)…

    13. 20 октября 2009

      > сколько терабайт по миру можно было бы съэкономить если бы в сайтах не было миллиардов ?
      упс. тут html код был порезан 🙂 должно быть так:
      «сколько терабайт по миру можно было бы съэкономить если бы в сайтах не было миллиардов [/span][/div][/strong]?»

    14. Олег Коровин
      20 октября 2009

      Сергей, обратите внимание на то, что в ИЕ6, если контейнером является таблица, то начинается бардак.

    15. Andrii Kasian
      20 октября 2009

      @stunpix
      интересно как ты себе представляеш без закривающейся конструкций такой код
      [div]
      [div] tesxt [/div]
      [div] yexy yexy [/div]
      [/div]
      в лучшем случаи yaml получиться

    16. 20 октября 2009

      В FireFox 3.5.3 1600х1200 выглядит так: http://www.blogdog.ru/tmp/div.png

    17. Сергей Чикуенок
      20 октября 2009

      Увеличил размер спрайта, теперь должно быть нормально

    18. 20 октября 2009

      @Andrii Kasian
      [div.header.selected:
      [div: tesxt]
      [div: yexy [bold: yexy] ]
      ]

      вариантов куча и фантазировать можно долго и идти надо не по принципу «сделать подобие html, но в другом синтаксисе», а полностью избавится от html подобия и сделать что-то удобно сочетающееся с ajax, позиционированием элементов на странице, а текст в угоду интернализации можно опционально вынести вообще из разметки в отдельный модуль аля:
      [div: @text_ref ]

      Только не стоит придираться к этим 3-ём строчкам, что тут так-то не то и это нельзя 🙂 это на вскидку придумано. и спецификации с кандычка так не решаются. 🙂

      Кстати вопрос к Сергею как к эксперту, т.к. я долго бился в одном проекте над задачей, но так и не решил. Может есть идеи как граммотно решить?
      Дано:
      [div id=»a»]
      [div id=»b»][/div]
      [/div]

      позиционировать #b внутри #a таким образом, чтобы #a изменял свои размеры в зависимости от положения #b. т.е. #a как-бы резиновый и его размеры зависят от положения и размеров #b…

      элегантного способа без js не нашёл… 🙁 как только #b объявляю position:absolute — #a тут же «схлопывается»… 🙁

    19. 20 октября 2009

      забыл добавить… 🙂 кроме #b конечно внутри #a так же могут быть элементы влияющие на размер #a как и #b 🙂

    20. GreLI
      20 октября 2009

      Сергей, позиционирование в правой нижней точке можно сделать через врэппер с допустимой (максимальной) шириной и таким же отрицательным левым отступом, а затем позиционируя сам блок относительно врэппера: { bottom: 0; right: -45px } (значения подбираются).

    21. egorinsk
      20 октября 2009

      Как я понял, проблема выставления блокам 1 и 2 нужной высоты в ИЕ решается тем, что там просто задана очень большая высота, и overflow:hidden на враппере? Интересное решение, я то пытался через одноразовый expression + обработчик onresize вычислять 🙁

      И на .d-shadow стоит поставить background: white, чтобы все нормально отображалось без картинок.

    22. Янис
      20 октября 2009

      А действительно ли использование одного огромного спрайта является лучшим в данной ситуации? Может быть, лучше использовать 2-3 маленьких спрайта?

    23. GreLI
      20 октября 2009

      Спрайт занимает от силы килобайт 10, и даже на модеме грузится 2–3 секунды, что сравнимо со временем четырёх запросов файлов (в сумме большего размера). А IE до 7 может делать только два запроса одновременно. На более быстром соединении выгода спрайта очевидна: один запрос — картинка мигом загрузилась. Только на сверхбыстром соединении с браузером и сервером, позволяющим много запросов будет всё равно. То есть практически только на локальном компьютере, ведь мы живём в реальном мире

    24. Сергей Чикуенок
      21 октября 2009

      И я думаю, что вы должны согласиться — html это язык разметки текста, а не фундамент для UI, RIA и ajax. Покажите мне хоть одного разработчика, который для создания UI и логики в своём софте будет всё лепить в ворде? Правда же нонсенс? Не, ну конечно оно-то можно… но каков результат будет? То же и с html — слепить-то можно, но какой ценой и затратами

      Вот, кстати, хороший пример. У меня есть программеры, который пишут под айфон. Там в плане создания интерфейса всё очень просто: есть только два возможных размера окна — портретный и ландшафтный. То есть слепил один раз интерфейс и забыл. Сейчас они начинают писать под Андроид, и тут началась веселуха: устройств много, размеры экрана абсолютно разные. Они сейчас открывают для себя такую вещь как «резиновые макеты» 🙂 Да, у веб-разработчика это вызывает ухмылку, но для программеров это проблема, потому что нет нормального и просто инструмента для реализации такого интерфейса. И именно поэтому связка HTML/CSS очень выгодна и проста в реализации. Именно поэтому всё больше и больше вендоров начинают внедрять браузерные движки в свои продукты, потому быстрее и проще.

      сколько терабайт по миру можно было бы съэкономить если бы в сайтах не было миллиардов [/span][/div][/strong]?

      Мне кажется, что ещё больше терабайт можно сэкономить, если запретить торренты и прочий файлообмен 🙂 Но ведь это не повод их запрещать, не так ли? Так и в вебе: есть масса способов сэкономить на объёме сайт, но почти никто этого не делает. И проблема явно не в избыточности html.

      позиционировать #b внутри #a таким образом, чтобы #a изменял свои размеры в зависимости от положения #b. т.е. #a как-бы резиновый и его размеры зависят от положения и размеров #b…

      Я вот так сходу сказать не могу, если не увижу, что именно нужно сделать на макете.

      Спрайт занимает от силы килобайт 10, и даже на модеме грузится 2–3 секунды, что сравнимо со временем четырёх запросов файлов (в сумме большего размера).

      Но есть другая проблема, на которую мало обращают внимание: объём занимаемой спрайтом памяти. Так что иногда действительно лучше пожертвовать парочкой отдельных запросов, нежели делать огромный спрайт. Подробнее тут: http://blog.vlad1.com/2009/06/22/to-sprite-or-not-to-sprite/

    25. Andrii Kasian
      21 октября 2009

      На скору руку наколбасоил один итересній вариант http://narod.ru/disk/14340577000/rounded.tar.gz.html

    26. Andrii Kasian
      21 октября 2009

      Так наверное будет проще посмотреть 🙂 http://to-kandy.narod.ru/rounded/t.html

    27. 21 октября 2009

      http://artqookie.ru/works/box_shadow/box.html
      Можно ли для такого варианта сделать инлайн? А прозрачность в ie6? А то сейчас юзеры на шестом ослике видят кукиш 🙂

    28. Роман
      21 октября 2009

      Вот еще один вариантик набросал, минимум CSS (5 строк), минимум HTML (2 элемента), 1 картинка, используются псевдо-классы :after и :before + небольшой *.htc файлик для ие, всё тянется, единственный минус не стал пока парится дли ие6 (да покарает его аллах ^_^)

      Собственна вот оно: http://mintdesign.ru/rounded_corners/index.html
      Если кому есть что дополнить буду признателен 🙂
      В будущем планирую доработать для ие6 и подробно описать в виде поста этот способ у себя на сайте.

      Тэстил в Опера 9.2+, FF 3.5, Safari (Win) 3, Google Chrome 3

    29. GreLI
      21 октября 2009

      Andrii Kasian, сложновато, радиус закруглений зависит от размеров, не слишком производительно (SVG в Firefox).

    30. 21 октября 2009

      Не работает тень в ие6 сборки 6.0.29000.5512.xpsp_sp3_gdr…

    31. 22 октября 2009

      Сергей, а какой движек под Айфон вы используете?
      почему его выбрали?

    32. Егор
      22 октября 2009

      Решение требует в IE обязательного указания doctype. Иначе разваливается

    33. Павел Золотарёв
      23 октября 2009

      Подтверждаю Yvelious. Не работает тень в IE6 сборки 6.0.3790.3959, на server 2003.

    34. Yoda
      26 октября 2009

      Сергей, спасибо за статью и очередную домашку, получил массу новых знаний 🙂

      Хотел бы услышать ответ на животрепещущий вопрос, не относящийся к теме. Очень давно сталкиваюсь с проблемой размещения absolute блоков внутри inline-block. Все чудно работает везде, кроме оперы 9.2 — блоки, позиционированные с помощью абсолюта куда-то пропадают 🙂 Подскажите пожалуйста, как это можно исправить?

      Структура примерно такая:
      [div style=»position: relative; display: inline-block;»]
      [div style=»position: absolute; left: 0; top: 0;»]this block disappears under Opera 9.2[/div]
      some text
      [/div]

    35. bvu
      28 октября 2009

      Andrii Kasian, проблема в том, что такое решение дает неприятный эффект в мозилле, его можно увидеть при скролле окна. Решение кстати для него я нашел недавно, но есть еще проблема, попробуйте открыть пример в вебките, такнетесь на белый фон. И это тоже решается, но к сожалению пока не получил нужного результата

    36. Артём
      31 октября 2009

      Сергей с чем связано, что на сайте башни не работает F11 (окно обозревателя на весь экран монитора) в FF 3.5.4 ?

    37. Артём
      3 ноября 2009

      В примере Сергея есть небольшая бага, а именно в 7 ИЕ, если блок .d-shadow поместить в любую таблицу, то перестает работать правило
      margin-left:100%; для блоков .d-sh-tr, .d-sh-br.

    38. Anton Poleshchuk
      9 ноября 2009

      у данного способа есть небольшой минус — снизу отступ от текста не может быть меньше высоты нижних блоков (например если декорация имеет большой радиус закругления и тень от блока достаточно далеко)

    39. Сергей Чикуенок
      9 ноября 2009

      Это можно попробовать решить через дополнительный блок и отрицательные марджины

    40. 12 ноября 2009

      Сергей, в ие6 есть проблема с высотой блоков
      .b-content-form__bl,
      .b-content-form__br {
      font-size: 0; /* эта штука помогает это вылечить */
      }

    41. 13 ноября 2009

      Статья полезная, но видать придется пару дней разбираться.

    42. Юрий
      16 ноября 2009

      > Это можно попробовать решить через дополнительный блок и отрицательные марджины

      Так ведь у блока в котором текст — overflow:hidden. Т.е. текст снизу будет обрезан.
      Поясните пожалуйста как это можно иначе реализовать.

    43. vladimir
      18 ноября 2009

      А почему примеры не работают в FF 2.0 ?

    44. 18 ноября 2009

      Возможно, кому-то пригодится и такой вариант: http://trifler.ru/blog/i/image/test_end.htm

    45. Евгений Самсонов
      6 декабря 2009

      Если под блоком есть другие элементы, то фон лезет под них. Как этого избежать? Пробовал различные манипуляции с z-index, но ничего не выходит.

    46. Евгений Самсонов
      7 декабря 2009

      Разобрался. Спасибо за отличное решение.

    47. 8 декабря 2009

      Смысл заморачиваться дивами если можно в разы проще сделать на таблицах и ничё ехать не будет когда тянуться будет?

    48. Вячеслав
      9 декабря 2009

      Сергей, интересно, будете ли вы править ваше решение? Как уже было сказано выше (но не прокомментировано вами) — ваше решение не работает в MSIE 6.0 (вообще, независимо от окружения блока), а лично у меня в MSIE 7.0 ломается, если блок в таблице.

    49. Сергей Чикуенок
      10 декабря 2009

      Решение работает в IE6 — просто не заметил, что сам спрайт сохранился как PNG с полупрозрачной палитрой. Сейчас олжно быть всё в порядке. А по поводу IE7 — это известная проблема использования margin-left:100% и таблицы. Решается заменой на right:0; (а для IE6 отдельно прописать margin-left:100%).

    50. 10 декабря 2009

      Кстати, пример в IE6 отображается без тени, потому что спрайт сохранен в формате png8, если использовать спрайт в png24, то пример работает корректно.

    51. vladimir
      10 декабря 2009

      а то что пример в FF 2.0 не работает — вы намеренно игнорируете?

    52. Егор
      10 декабря 2009

      vladimir,

    53. Егор
      10 декабря 2009
    54. Vladimir
      10 декабря 2009
    55. Егор
      11 декабря 2009

      vladimir,

      Да, действительно, вы правы в FF версии 2.0.x пример Сергея не совсем корректно себя ведет относительно нижних декоративных элементов.

      Причина в CSS-свойстве «z-index» этих элементов. В своем решении Сергей задает это свойство всем уголкам через класс «.d-sh-cn». Для нижних элементов это свойство указывать не обязательно, поэтому вы можете избавится от этого неприятного эффекта, просто убрав свойство «z-index» из класса «.d-sh-cn», и добавив еще еще один селектор для верхней пары уголков, типа такого:

      .d-sh-tl,
      .d-sh-tr {
      z-index: -1;
      }

      Таким образом вы понизите на один пункт только верхнюю часть декоративных блоков.

      В моем примере, картинку на который я вам показывал с самого начала, я обошелся вовсе без свойства «z-index» для декоративных элементов.

      Я просто разместил контейнер с содержимым блока (тег «P» в примере Сергея) по коду после div-ов верхних уголков и добавил ему свойство «position» с значением «relative».

      Возможно, такое не совсем корректное с точки семантики, решение с относительным позиционированием покажется вам более простым.

    56. boronchiev
      4 января 2010

      Добрый вечер!
      Столкнулся с непонятным мне поведением браузеров, разбирая пример. При переходе к якорю, находящемуся внутри декорированного блока, текст подскакивает вверх и обрезается блоком .d-shadow-wrap без учета его полей. Такое поведение наблюдается во всех браузерах (тестировал только под Windows), кроме Opera.
      На основе Вашего примера сделал тест http://boronchiev.ru/cor/
      Если убрать элементы, которые декорируют верхние углы, поведение становится ожидаемым мною. Пока не смог найти объяснение. Буду рад, если Вы подскажите, в каком направлении думать.

    57. Иван
      7 января 2010

      Сергей, спасибо за труд! Добавлю, что для корректной работы в FF2- нужно добавить .d-shadow какой-нибудь z-index.

      boronchiev: насколько я понимаю, это из-за того, что у .d-shadow-wrap внутренняя высота больше внешней из-за распирающих верхних блоков, и прокрутка срабатывает внутри него. Если у .d-sh-tl и .d-sh-tr заменить height: 1500px; на bottom: 0; или height: 100%; padding-bottom: 28px;, это исправит ситуацию для всех, кроме IE6. Для него кроме expression ничего пока не придумал.

    58. 11 января 2010

      #mycoolblock {
      border-radius: 1em;
      box-shadow: rgba(10,10,10,0.5) 5px 5px 5px; }
      И все!
      Зачем делать красивости в IE6? Самое правильное решение: в старых браузерах все показывается без теней и уголков. И надпись «чтобы было красиво и быстро, установи Google Chrome».
      Полная поддержка IE6 (с красивостями) тормозит развитие нормальных браузеров.

    59. Артур
      26 января 2010

      Сергей, огромное спасибо!
      Буду учиться, учиться и еще раз учиться! 🙂

    60. Иван
      29 января 2010

      Сергей, а можно пример работающего декорированного инлайн-блока в IE6?

    61. Роман
      1 февраля 2010

      Поддерживаю вопрос Ивана, на счет декорированного «инлайн» элемента в IE6 🙂
      Блоковый элемент вообще не очень универсальный. Т.к. инлайн-элемент можно легко переделать в блок, а вот блок в инлайн уже не так просто.

      Уже неделю потихоньку ковыряюсь с этой конструкцией, но пока не нашел окончательного универсального решения для IE6. Вся сложность заключается как раз в растягивании элементов по вертикали.

      vii, reverse и Олег Коровин решают эту проблему перегоняя IE6 в backCompat mode с помощью вставки
      Получается почти идеальное решение. И можно даже смирится и писать всё учитывая особенности quircksmode, хотя в некоторых случаях это может быть не приемлимо.

      Так же, можно сделать эту конструкцию в css1Comp режиме, но она работает только если декорированный объект находится в статичном блоке. Если блок имеет %% размер, то при изменении размера окна декорации умирают.
      При это так же необходимо подключать фон только через фильтр… правда еще не до конца разобрался с этим.

      В принципе, это все относится к блокам с полу-прозрачным фоном, т.к. если декоративные элементы без прозрачности — это решается растягиванием элементов по вертикали до «заоблачных» размеров.

    62. 25 февраля 2010

      Не слишком универсальный способ, если нужно декорировать блок по высоте неограниченного размера

    63. GreLI
      19 апреля 2010

      Роман, смотрите мой пример. Как решение случая с шириной, зависящей от содержимого, он подходит и для строчных блоков.

    64. Андрей
      21 апреля 2010

      Сергей, очень понравился ваш пример, начал с ним разбираться и в процессе заметил, что при масштабировании в нижнем правом углу появляется зазор.

    65. 5 мая 2010

      Лично мне нравятся вот эти примеры — нет картинок — к сожалению, есть жаба

      ruzee borders — http://lev19888.narod.ru/10.html
      http://lev19888.narod.ru/11.html

    66. Санек
      6 октября 2010

      Эх. Вообще очень круто. Но вот если этот самый блок заставить расширяться jquery animate то в момент движения все эти тени отображаться не будут =( Как вот с этим-то бороться?

    67. Сергей Чикуенок
      6 октября 2010

      у jquery.animate есть одна неприятная особенность: постоянно жёстко включается overflow: hidden. Поэтому лично я редко использую jquery для анимации

    68. Илья
      1 декабря 2010

      Сергей, а подскажи, каким образом ты делаешь подобные спрайты? Я до сих пор делаю их руками в фотошопе. То есть полностью руками.

    69. 1 декабря 2010

      Илья, здесь хорошо описано:
      http://chikuyonok.ru/2009/03/photoshop-for-webdevs-2/

    70. 2 декабря 2010

      А у меня такая проблема, всё работает нормально кроме как в IE, вот ссылка для наглядности (http://www.goodnet.ru/?/goodnet/outsourcing/it-infra), верстаю недавно, так что проблема может быть тривиальной.

    71. Артём
      23 февраля 2011

      Использую этот способ для верстки выпадающего меню. Вместо P в примере Сергея у меня UL.

      В IE7 некорректно работает. Если не укажешь у .d-shadow-warp свойство background с цветом спрайта, то на этом месте он не отображается. Края картинок слева, справа и снизу есть. А в центре пустое место с элементами меню.
      Но и при моем своеобразном хаке есть минус — тени сверху не будет.

      А в IE6 словно принудительно включено у .d-shadow-warp свойство width:100%. То есть ширина каждого выпадающего меню становится равной ширине самого большого из них. А мне надо, чтобы ширина была по контенту.

      Как можно побороть эти проблемы?
      Буду очень признателен за любую помощь =)

    72. 24 сентября 2011

      Спасибо!

    73. Nikita
      31 марта 2012

      Я так понял в вашем примере растягивание по горизонтали и вертикали ограничивается размерами картинки… Не подскажите как сделать блок без тени, но резиновый по вертикали и с возможностью менять значение ширины в коде, работающий в IE 6 и выше. И ещё будет замечательно если покажите как приклеить к нему стрелку такого вида < слева, что бы она всегда находилась по центру блока(балуна)?

    74. sebastjan
      11 мая 2012

      Мне кажется что пример с обложками книжек не очень подходит.
      Проще сделать сразу эти обложки с тенью чем делать под них блок с тенью.

    75. 26 мая 2012

      Куль. Все подходит