Задача: сделать врезку с закругленными уголками с минимумом html-кода.
Все наверное сталкивались с врезками с закруглёнными уголками. Поскольку множественный бекграунд современные браузеры (кроме Safari) не поддерживают, то такие вещи приходится делать несколькими элементами, вложеными друг в друга. Есть способ уже сейчас избежать подобных вещей.
html-код:
Текст
css-код:
Задаем голубой фон врезки:
.incut{background: #dff7ff;padding: 20px;}
Четыре уголка навешиваем на элементы :before и :after
.incut:before{
content:url(i/border_tl.gif);
background: url(i/border_tr.gif) no-repeat 100% 0;
height: 7px;
display: block;
margin: -20px -20px 13px -20px;
}
.incut:after{
content:url(i/border_bl.gif);
background: url(i/border_br.gif) no-repeat 100% 0;
height: 7px;
display: block;
margin:13px -20px -20px -20px;
}
Работает во всех современных броузерах кроме ie (проверял в Firefox 1-2 Opera 7-9,Safari 3). Для ie аналогичный функционал навешиваем с помощью js (лучше помещать в отдельный файл css – специальный для ie):
.incut{zoom:1;behavior:expression(!this.isInserted==true ? this.isInserted=(this.innerHTML = '
' + this.innerHTML + '
') : '');}
Работает в ie6-7. При отключеных скриптах пользователь ie увидит голубой фон у врезки, т.е. ничего не сломается.
В результате имеем «пуленепробиваемую» врезку с минимум html-кода. Заметьте, что вы можете указать ещё одну картинку у врезки, которая будет её бекграундом.
Применяя эти псевдоэлементы аналогичным образом можно значительно увеличить семантичность верстки. Всё зависит от вашей фантазии.
UPD:
Примеры смотреть
тут.
комментарии (145)
Думаю в данном случае вполне допустимы.
С чего вы взяли, что в разработке спецификации не было MS CSS? Опять же был бы рад ссылке на беспочвенное утверждение.
В одном предложении 2 существенные ошибки...
конечно проще закрыть глаза на проблему и не признавать ее, нежели единожды решить... но куда девать маркетинг? каким еще "магическим" способом заставить пользователей "сидеть" на своей поделке?.. приведите хоть один (не промоушен) сайт, скажем, опера-онли...
не считайте себя умнее тысяч веб-разработчиков и веб-дизайнеров, для которых этот продукт даже не кость в горле...
С чего вы взяли, что IE поделка? На поделке сидит > 2/3 пользователей. Что за тон в отношении компаний? Вы хоть раз занимались поддержкой продукта имеющего > 10000 копий(я не говорю уже о нескольких десятках миллионов продуктов основаных на движке IE)? Вы представляете сколько будет стоить переделки всех систем использующих движок IE? Мы не в состоянии собрать даже 0.00001% этой суммы. А кричите - долой\бойкот.
Ни кому он ни кость, поскольку, тысячи веб-разработчиков, в отличии, от кричащих, прекрасно знают все 'особенности' IE и способы как решать эти проблемы. MS прекрасно общается с ними. Попробуйте немного почитать их сайт.Не будте смешны в их глазах с криками о бойкоте.
За '-' отдельное спасибо. Это самый самый сильный довод с вашей сторон ;). Попробуйте научиться вести дискуссию, хотя бы уважая собеседников.
> Это ваше право считать нормальным то количество костылей и подпорок, которые заставляют ие показывать так, как этого хочет дизайнер
> На поделке сидит > 2/3 пользователей.
Это вообще никак не характеризует программу... На ВАЗ тоже много народу ездит, но лучше он от этого не становится.
> Вы представляете сколько будет стоить переделки всех систем использующих движок IE?
Не понимаю для чего нужно переделывать все существующие программы, использующие эту поделку. Можно было просто сделать нормальный браузер еще в шестом поколении.
> Что за тон в отношении компаний?
ммм... а каким должен быть тот? и что за тон у меня?
> Не будте смешны в их глазах
Буду стараться, спасибо
Попробую разобрать по полочкам.
zoom:1; - исправляет баг с лайот для ие, где-то на хабре была статья про это. Это универсальный способ правки многих глюков для ie.
behavior фактически искуственно добавляет требуемые псевдоэлементы для ie. Наша задача: добавить два элемента - перед основным содержимым элемента и после, для этого используем this.innerHTML=Элемент1+this.innerHTML+Элемент2. Но добавить это нужно всего один раз, поэтому используем expression: для элемента искусственно вводим некий атрибут isInserted. Если этот элемент еще неопределен (!this.isInserted=true), то задаем этому атрибуту значение (this.isInserted=(что-то определенное)), если уже определен (!this.isInserted!=true), то ничего не делаем. Как видно Элемент1 и Элемент2 в точности соответствуют псевдоэлементам :before и :after
В этом случане не вводится переменная и не проверяется постоянно.
Вот выпустит через пару лет Майкрософт какой-нибудь нормальный браузер, или пользователь юзает браузер, не умеющий ни :after, ни expression в цссках — что будем делать?
Псевдоэлементы :after и :before — стандартные. И если вдруг случится чудо и Microsoft выпустит «нормальный» браузер, поддерживающий стандарты, то все будет просто хорошо =)
У пользователя с таким браузером просто будет блок одного цвета и все.
Лично я не могу сказать, что вот этот способ превосходит метод, описанный выше. Просто сравните html-код.
Можно подключать css-файл для ie не выше 7.0
Этот вариант валиден, работает везде, работает с отключёнными картинками и яваскриптом. Да, он захламляет код по сравнению с обсуждаемым вариантом, но без жертв в нашей профессии никак. Лично мне четыре-пять строк в коде не мешают.
Которое, в отличии от описанного в статье работает без всяких ограничений. И нечего ставить "-" если вы не в теме...
а то что автор поста предлагает — вполне ничего
Многие движки по генерации превьюшек не понимают JS, зато понимают стили и бекграунды.
Уж лучше код будет на 2 Кб больше, но валидно и однозначно отображаться везде.
А что такое движок по генерации превьюшек? (Простите, если вопрос глупый ;) )
Генератор превьюшек - это программа, генерирующая уменьшенный вид страницы и отображающая его в виде графического файла. Например, расширения для огненного лиса и Google: http://ackroyd.de/googlepreview/
По сравнению с multiple backgrounds (поддерка только в Safari) — это всё костыли, поэтому играем по правилам военного времени.
Если просто wrap, то не интересно.
P.S.:
И в Сафари можно так: -webkit-border-radius: 10px; =)
Анти-алиасинга не было и нет, увы :(
Вообще, конечно, странно и обидно, что до сих пор браузеры не научились делать качественные элементарные графические "рюшечки" вроде -moz-border-radius + anti-aliasing.
-moz-border-radius
это черновые реализации css3
НО:
Для проектов, нацеленных на рядового пользователя это рак. Доля ИЕ - значительно больше половины. Джаваскрипт хаки приводят к мерцанию для hover элементов.
Кроме того решение не универсально, как уже сказал prolis.
>>Джаваскрипт хаки приводят к мерцанию для hover элементов
Не понимаю, что замерцание. У меня ничего не мерцает, поясните подробнее
Это не конкретно вам - замечу что пример в статье будет работать при правильном DOCTYPE
Но на проектах где пользователи ИЕ составляют не доминирующий процент я думаю юзать этот метод обязательно!!!
А какого размера в пикселях должны быть эти гифы border_*.gif?
Но естествено можно использовать и другие, поправив код
вот такой:
http://design.loreto.ru/ff.jpg
Пример "экспериментального" html такой:
Example
@import "main.css";
@import "print.css";
@import "fix_ie.css";
Текст
css Ваш на 100%
Почему глюк имеет место быть?
Кстати, в IE все OK!
вот такой:
http://design.loreto.ru/ff.jpg
Пример "экспериментального" html такой:
http://design.loreto.ru/ex.html
css Ваш на 100%
Почему глюк имеет место быть?
Кстати, в IE все OK!
Берите этот DOCTYPE:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3c.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">Ну супер. Это решение на порядок элегантнее, чем с различными использованиями ява-скриптов. Надо будет использовать.
И протестировать с доктайпом strict
а то что для ie применяются отдельные правила (которые даже рекомендуют выносить в отдельный файл) - это уже давно норма.
не уверен, что во всех случаях, правда. у меня был css класс с expression на ie, который был проаплпен на input элементы. при создании input'а через скрипты начинались жуткие тормоза.
А то полдня бьюсь - не получается полностью красиво.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3c.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251" />
<style>
body{padding:30px}
.incut{background: #dff7ff;padding: 20px;}
.incut:before{content:url(i/border_tl.gif);background: url(i/border_tr.gif) no-repeat 100% 0;height: 7px;display: block;margin: -20px -20px 13px -20px;}
.incut:after{content:url(i/border_bl.gif);background: url(i/border_br.gif) no-repeat 100% 0;height: 7px;display: block;margin:13px -20px -20px -20px;}
.incut{zoom:1;behavior:expression(!this.isInserted==true ? this.isInserted=(this.innerHTML = '<span style="background: url(i/border_tr.gif) no-repeat 100% 0;height: 7px;display: block;margin: -20px -20px 13px -20px;"><img src="i/border_tl.gif" alt="" /></span>' + this.innerHTML + '<span style="background: url(i/border_br.gif) no-repeat 100% 0;height: 7px;display: block;margin:13px -20px -20px -20px;"><img src="i/border_bl.gif" alt="" /></span>') : '');}
</style>
</head>
<body>
<div class="incut">
Текст
</div>
</body>
</html>
Картинки с уголками имеют ширину 8px а высоту 7px
В очень старых браузерах пользователи просто не увидят закругленные уголки. Из-за этого сайт ваш поверьте не покинут, они даже знать не будут, что там должны быть уголки.
При редизайне сайта, тоже будете по всему контенту лазить, менять на пять дивов если вдруг дизайнеры сложнее перерисуют? А если сайт большой, корпоративный? Поверьте, подобных сайтов встречал не мало.
А 4 дива использовать лучше, потому что голый HTML всегда надежней неоправданного использования скриптов.
Товарищи, все эти методы закругления уголков у элементов БЕЗ использования картинок — это, конечно, прекрасно, но посмотрите в самом начале темы, как звучит задача проекта.
Если далее. Вот вы говорите, что тема не раскрыта, ибо в ie используется js. А теперь скажите, кто в основном эти люди: пользователи ie? Я сам отвечу. В основном это те, которые даже не подозревают о существовании других браузеров, более удобных, быстрых, функциональных, которые не могут себе представить, что ie, идущему в стандартной комплектации Windows, существует множество альтернатив. Вы думаете, этим людям интересно, как сделаны закругленные уголки у элементов? Они есть. И это главное.
а в css 3 есть стиль для скругления углов...
http://www.w3.org/TR/css3-background/#th…
всё на своих местах, кроме правого верхнего уголочка =/
что-то не придумывается как его опустить)
в сафари такого нету =/
p/s/ изображение (фотку, аватарку и т.д.) хотелось бы видеть именно как img src="... , а не ложить его бекграундом...
1. при увеличении шрифта - левые уголки смещаются вниз
2. при фиксированной высоте блока и малом количестве его содержимого(ну вот надо было так) - уголки соотв. становятся после контекста и вниз их ну никак не загнать...
по второй "неприятности" еще можно сказать что этот способ не для этого... - согласен
но вот первая "неприятность" сводит на нет очень даже неплохой способ избавиться от пары-тройки дивов(и прочих левых)...
Да ничего не смещается. Я наверное что-то делал не так =)
>>2. при фиксированной высоте блока и малом количестве его содержимого(ну вот надо было так) - уголки соотв. становятся после контекста и вниз их ну никак не загнать...
Ну а кто вам мешает разобраться чуть-чуть в коде и переписать пример под фиксированную высоту блока?
>>для :before и :after прописать "line-height: 0.1;".
1) задний фон — картинка, убирающаяся к правому краю и создающая тень справа
2) нижний-правый угол — картинка огромной ширины (2000x8), содержащая не только нижний-правый угол, но и весь низ с тенью
вечером, если интересно, могу выложить вырезанный блок из мозиллы. насколько помню, он никуда не ездит ни в одном браузере.
p.s. приятно, однакоЖ..., самому дойти до этого :))))
про "line-height: 0.1;" и сам хотел написать тока во опередили меня :)
тока я бы написал line-height: 0 - это надо для Оперы, а для FF уже решил еще одной строкой... font-size: 0;, если без нее то получается то что писал выще - уголки едут вниз (ну уже понятно из-за чего)...
мешает спецификация:
12.1 Псевдоэлементы :before и :after
Агенты пользователей должны игнорировать следующие свойства с псевдоэлементами :before и :after: 'position', 'float', свойства списков и свойства таблиц.
если можно еще "как-то" это сделать - очень было бы интересно, потому как пригодилось бы...
Все уже открыто и исследовано до него. Да и странный топик. Вроде как велосипед изобретён уже давно.
Больше как 3 года все нормально катаются. Жаль, что кто-то не в курсе. Есть полно валидных решений на чистом CSS.
А использовать JS и кучу вещи, которые IE не поддерживает - увольте, читайте книжки(блоги).
1)Не понятно кто и как рейтингу :). * n1313 8 октября 2007 15:31 дал корректную ссылку, где начинающие могут немного посмотреть на работы профессионалов, и кто это оценил?
2) Кто мне приведёт ссылку на СТАНДАРТ в CSS? Ставлю ящик пива. Есть спецификация(подчеркнуто), которая написана несколько туманно и некоторые вещи отданы на откуп пользовательским агентам(броузерам), так что на IE местами нечего пинать. Сравните время его выхода со временем последней редакции спецификации CSS 2
а чем этот метод не профессионален???
по мне так лучше в коде видеть запись вида
<div class="box">
текст
</div>
чем как у "бескартиночных" профессионалов с cssplay
<div class="box">
<b class="top"><b class="b1"/><b class="b2"/><b class="b3"/><b class="b4"/></b>
<div class="boxcontent">
текст
</div>
<b class="bottom"><b class="b4b"/><b class="b3b"/><b class="b2b"/><b class="b1b"/></b>
</div>
или с теми же картинками как минимум еще с пару блоками внутри (к примеру, без учета конкретного дизайна)
<div class="box">
<div class="top"><div></div></div>
текст
<div class="bottom"><div></div></div>
</div>
да, есть у "нас" 6-ка, всмысле ИЕ :)... ниче с этим не поделаешь...
http://illandril.net/jQuery/transparentCorners/cornerTests.html
Проверял в разных броузерах-> (IE6&7/Opera/FF) - работает!
Есть замечательная ошибка в IE, "operation aborted". Возникает когда пытаемся изменить DOM-дерево до загрузки всей страницы. Может возникнуть при использовании данного метода.
Вариант лечения:
.incut{zoom:1;behavior:expression(!this.isInserted==true && iDOMLoaded ? this.isInserted=(this.innerHTML = '<span style="background: url(i/border_tr.gif) no-repeat 100% 0;height: 7px;display: block;margin: -20px -20px 13px -20px;"><img src="i/border_tl.gif" alt="" /></span>' + this.innerHTML + '<span style="background: url(i/border_br.gif) no-repeat 100% 0;height: 7px;display: block;margin:13px -20px -20px -20px;"><img src="i/border_bl.gif" alt="" /></span>') : '');}
И перед </body>:
<script type="text/javascript">iDOMLoaded = 1;</script>вобщем вот мой вариант для ИЕ
функция insertAdjacentHTML вместо прямого обращения к innerHTML, соотв с параметром 'afterBegin' вставляет после начала тэга (перед контентом - аналог :before) и 'beforeEnd' (аналог :after) - вставляет до закрытия тэга...
вместо проверки !this.isInserted==true используется runtimeStyle.ххх что заставляет ИЕ не пересчитывать expression при каждом движении мыши...
подробней описано тут http://lusever.ru/proceedings/thin_css/index.html
.incut {
zoom:expression(
runtimeStyle.zoom = 1,
insertAdjacentHTML('afterBegin','...ххх...'),
insertAdjacentHTML('beforeEnd', '...ххх...')
)
}
вот, например вместо ...ххх... нужно писать сам код, который хочу вставить? к примеру
<span style="background: url(i/border_tr.gif) no-repeat 100% 0;height: 7px;display: block;margin: -20px -20px 13px -20px;"><img src="i/border_tl.gif" alt="" /></span>для 'afterBegin'
отец.
большое спасибо за экспрэшены для after и before
совершенно немогу понять людяй кричащих что expression плохо, зато несемантические элементы и примитивизм в css - это хорошо.
а чтоб экспрэшены не подвешиали их, как верно заметили, нужно оптимизировать и вызывать лишь один раз.
Никак не получается вывести их наверх, если картинка задается тегом img, а не бекграундом, то она всегда поверх блоков :before и :after, какое бы позиционирование и z-index им не задавай…
В правом блоке картинки окружены рамочкой с закруглением — посмотрите.
Но я рад, что у вас получилось)
Z-index для картинки нужен когда уголки задаются фоном, а у вас через content. Кстати, для IE7 тоже нужно добавлять блок .after вручную.
довольно геморно это…
www.gymn1sam.ru/
В правой колонке картинка на главной
и в контенте есть
Там проблема в том, что float нужен