Нестандартные обтекаемые блоки
Четверг, Январь 7, 2010 19:49
Доброго времени суток. Это первый пост в Новом году =).
Предложили работу. Верстка сайта, на вид довольно таки простая. Но взглянув в ТЗ (техническое задание) понимаешь, что сайт продуман до мелочей. И сейчас я напишу подробнее об одном из пунктов.
Верстка главного меню: само главное меню состоит из 1 и 2 части. То есть 1 и 2 — два различных меню. Из шаблона видна ситуация, когда 2 идет после 1 (см. название слоев). Но когда оба меню не помещаются в одну строчку, то второе находится над первым (как показано на слое «Меню Ситуация 2»).
Сразу, когда я принялся за верстку этого меню, у меня в голове не было никаких идей. Я даже собирался использовать javascript, что заказчик полностью разрешил.
Но решение само как-то пришло на следующий день. Благо, время позволяло переделать, прикрутить и завершить верстку всего сайта вовремя.
Сразу из цитаты покажу два рисунка, созданные на основе оригинального шаблона:
Ситуация 1 — когда второй блок, содержащий текст «главная», идет после первого, содержащего текст «категория».
Ситуация 2 — когда второй блок, содержащий текст «главная», размещается над первым, содержащим текст «категория».
Теория! Имеем два блока, но задаем им display:inline, чтобы убрать блочные свойства. В коде располагаем второй блок на первом месте. А первому в css прописываем обтекание по левому краю (float:left). Тогда у нас получается что при маленьком контенте первый идет первым, второй — вторым. И при увеличении контента одного или двух из блоков, то второй располагается над первым. Что нам и нужно было. Но не все так просто. Внутренние элементы должны сохранять свою ширину в зависимости от контента и обладать свойствами линейных элементов. Поэтому я отказался от привычных списков для меню и использовал обычные ссылки. При чем для них применил свойство display:inline-block, для того, чтобы можно было задавать фон картинкой и чтобы обладала свойствами линейных элементов.
Код!
html:
<div id="wrap">
<div class="block2">
<a href="">Главная</a>
</div>
<div class="block1">
<a href="">категория</a>
</div>
<div class="clear"></div>
</div>css:
.block1{float:left;}
.block2 a{
/* Дальше идут хаки для использования display:inline-block; */
display:-moz-inline-stack;display:inline-block;_overflow:hidden;zoom:1;*display:inline;
}
Как вы могли заметить, я использовал хак для многих браузеров, связанный со свойством display. Я вам показал просто блоки без оформления. Вот теперь я вам покажу реальные стили, которые я использовал для верстки этого меню.
.block2{margin-bottom:10px;}
.block1{float:left;margin:4px 0 0 5px;}
.block2 a{
background:#ebebeb url('menu-bg.png') no-repeat 0 0;
width:90px;height:21px;text-align:center;padding:5px 0;font-size:18px;
/* Дальше идут хаки для использования display:inline-block; */
display:-moz-inline-stack;display:inline-block;_overflow:hidden;zoom:1;*display:inline;
}
.block2 a:hover{color:#ccc;}
.block1 a{font-size:15px;text-decoration:underline;color:#414141;padding:0 5px;}
.block1 a:hover{text-decoration:none;}
Все хорошо, красиво, но в IE версии 6 и 7, второе меню не обтекает первое по правому краю. Как бы я ни старался, я все равно не получил желаемого эффекта. Но заказчик одобрил отображение в IE этих версий.
Мы имеем красивые менюшки с нестандартным обтеканием. Очень жаль, что мне не удалось добиться полной кроссбраузерности, но адекватно пример ведет себя в следующих браузерах: Opera 9.6.3 и выше (ниже не тестировалось), Mozilla 3.5.2 и выше (ниже не тестировалось), Konqueror 4.3.4 (ниже не тестировалось), Rekonq 0.3.0 (ниже не тестировалось), IE 8 и выше.
Если у вас другой браузер и этот пример работает или не работает там, то большая просьба, сообщите об этом в комментариях.
remitmaster сообщил:
Январь 7th, 2010 21:13
Ну что сказать, не стандартная задача и хорошее решение. IE конечно в своем репертуаре
Vic сообщил:
Январь 11th, 2010 20:58
опера9.63 мозила3.5.2 — тож нормально. хотя пример не показателен, надо было один пример и чтоб при ресайзе эффект проявлялся. пришлось самому немного модифицировать код чтобы посмотреть как оно. хотя не верится что нельзя сделать это проще и без хаков...
WebMast сообщил:
Январь 12th, 2010 16:36
Vic, к сожалению я не смог придумать другого варианта. Да, мы жертвуем пятью ошибками, но ничего поделать с этим нельзя.
Если кто-то знает другой вариант, я буду очень за, если вы поделитесь =).
Vic сообщил:
Январь 12th, 2010 20:46
тут еще один момент. я не совсем понял постановку задачи. т.е. для крайнего варианта все понятно, но как должен себя вести этот активный пункт если он находится не с краю а посередине. а если он первый? если тоже вверху при нехватке места то для описанного метода очень громоздкое построение получается. таким образом надо заводить еще один класс и отдельный блок для пунктов справа от активного. в общем для меню способ не катит. хотя для частного случая верстки нескольких блоков применить можно... но эти хаки и несовместимость...
WebMast сообщил:
Январь 13th, 2010 16:10
Не совсем понимаю, что значит «активный пункт»?
Vic сообщил:
Январь 13th, 2010 19:23
активный пункт меню. в статье это пункт «главная».
WebMast сообщил:
Январь 13th, 2010 20:18
Ну, во-первых активный пункт идет только с правой стороны. Если бы он был слева и при нехватке места был сверху, то реализовывалось бы это другим расположением блоков на странице и намного проще. Вообще, этот пример и задумывался для частного случая. Чем это плохо?
Фей сообщил:
Январь 20th, 2010 16:17
В Мозиле 3.0.6 меню категория располагается под меню Главная и никак влево не сдвигается
Фей сообщил:
Январь 20th, 2010 16:40
ааа, если активный пункт всегда справа, то для block2 float:right
block1 float:left и wrap играться немного шириной. Тогда в Мозиле 3.0 вроде нормалек
Dmitriy сообщил:
Февраль 22nd, 2010 23:42
CSS сильная штука, надо подтянуть её... Особенно про «хаки» =)