Ссылка с возможностями блока
Дата публикации: 15.02.2010
Задача
Сделать ссылку для вот такого блока
При чем кликабильной должна быть вся область блока.
На что стоит обратить внимание:
- ссылка должна иметь четко заданную ширину (width)
- ссылка должна иметь четко заданную высоту (height)
- ссылка должна иметь внутренние отступы (padding)
Для облегчения задачи упустим тот факт, что такой блок в реальных условиях может быть еще и резиновым.
Когда я первый раз столкнулся такой задачей, первое, что пришло мне в голову — сделать все предельно просто:
<a href="#">Информация о Германии</a>
a { width: 71px; height: 33px; background: (path-to/about-germany.png); padding: 20px 30px 20px 83px; }
Попробовав так сделать и посмотрев на результат, вспомнил, что размеры и padding-top / padding-bottom работают только для элементов уровня блок. А ссылка у нас — это строчный элемент. Какие проблемы? Сейчас сделаю блок!
<a href="#"><div>Информация о Германии</div></a>
a div { width: 71px; height: 33px; background: (path-to/about-germany.png); padding: 20px 30px 20px 83px; }
Это сработало. Но радовался я не долго. Проверка на соотвествие стандартам меня несколько огорчила:
Оказалось, что элементы уровня блок нельзя вкладывать в элементы уровня inline (строчные элементы). Еще подумав, пришел к выводу, что без помощи javascript тут не обойтись:
<div onclick="location.href='#'">Информация о Германии</div>
Это решение соответствовало дизайну и проходило валидацию. В таком виде я сдал работу, в которой впервые встретилась подобного рода ссылка. Неудивительно, что этот заказчик больше никогда и ничего у меня не заказывал. Ведь я сделал из простой задачи большую проблему, и решить ее смог только с помощью javascript. А достаточно знать немного лучше CSS и тогда решение становится простым и изящным:
<a href="#">Информация о Германии</a>
a { display: block; /* меняем способ отображения элемента на блочный */ width: 71px; height: 33px; background: (path-to/about-germany.png); padding: 20px 30px 20px 83px; }
Более сложный вариант
Чтобы лучше усвоить урок, усложним задачу:
Такая задача — обычное дело при верстке каталогов товаров, интернет магазинов. Чтобы было понятней в чем сложность, приведу обычные требования к такому блоку:
- картинка должна быть вставлена тегом <img>
- картинка должна скругляться версткой (чтобы редакторы не тратили время на скругление в фотошопе каждой картинки)
- размеры блока с фото и самого фото жестко фиксированы (чтобы все картинки в каталоге были одинакового размера)
- фото и текст должны быть кликабильны, при чем в коде должен быть всего один тег <a>
Набросаем себе алгоритм реализации:
- если нужен только один тег <a>, значит он должен быть основным контейнером
- т.к. размер фото фиксирован, достаточно будет одного элемента для рамки, которая будет округлять углы фото
- картинку и рамку разместим с помощью абсолютного позиционирования, причем рамка должна быть поверх фото, чтобы закруглить углы
- текст разместим в нужном месте за счет внутренних отступов (padding)
Подготовим материалы:
<a href="#" class="photo"> <img src="path-to/photo.jpg" width="214" height="160" alt="" /> <span></span> Экстерьер и интерьер </a>
.photo a { display: block; width: 181px; padding: 176px 20px 0 15px; /* позиционируем текст внутренними отступами */ text-transform: uppercase; font-size: 11px; color: #298db2; position: relative; /* чтобы дочерние элементы позиционировались относительно границ ссылки-контейнера */ } .photo a:hover { color: #FF0000; } .photo a img { position: absolute; /* фото и скругленние углов позиционируется абсолютно, чтобы не влиять на положение текста */ top: 0; left: 0; z-index: 1; /* у фото должен быть z-index меньше, чем у скругленных углов чтобы рамка с углами была на фото */ } .photo a span { /* в ссылку вкладываем span: нейтральный элемент и код будет валидным */ display: block; /* отображение span меняем на блок */ width: 215px; height: 160px; background: url(path-to/photo-corners.png); /* рамка с прозрачным содержимым и скругленными углами */ position: absolute; top: 0; left: 0; z-index: 2; /* рамка должна быть над фото */ cursor: pointer; /* чтобы IE вложенным элементам при наведении тоже показал правильный указатель */ }
Заметка
В данной ситуации можно было не указвать явно z-index, т.к. элемент идущий по коду ниже, будет расположен выше по z-оси.
Проверено в:
Такой техникой можно смело верстать более сложные конструкции с большим количеством вложенных элементов и при этом код будет оставаться валидным.