Красивое выпадающее меню. Полупрозрачное и с тенью.

веб-дизайнер, February 24, 2009

Вот такое:

Нравится?:-) Научить, как делать нечто подобное? Устраивайтесь поудобнее, мы начинаем.
Начать следует с того, что сейчас большинство выпадающих меню (как горизонтальных, так и вертикальных) делают из несортированных списков (тег <ul> (сокращение от unordered list)). В совокупности с свойствами display:none и display:block (последнее для псевдокласса :hover, хотя, можно сделать и так, чтобы пункты меню прятались при наведении на них курсора мыши, да) получаются красивые и динамичные менюшки.

В данном меню html код выглядит так:

<div id=”shad”>
<ul>
<li><a href=”#”>Главная</a></li>
<li><a href=”#”>О нас</a>
<div id=”shad2″>
<ul>
<li><a href=”#”>История</a></li>
<li><a href=”#”>Команда</a></li>
<li><a href=”#”>Офис</a></li>
</ul>
</div>
</li>
<li><a href=”#”>Услуги</a>
<div id=”shad1″>
<ul>
<li><a href=”#”>Веб-дизайн</a></li>
<li><a href=”#”>Интернет</a></li>
<li><a href=”#”>Хостинг</a></li>
<li><a href=”#”>Доменные имена</a></li>
</ul>
</div>
</li>
<li><a href=”#”>Контакты</a>
<div id=”shad3″>
<ul>
<li><a href=”#”>Телефон</a></li>
<li><a href=”#”>E-mail</a></li>
<li><a href=”#”>Почта</a></li>
</ul>
</div>
</li>
</ul>
</div>

Если посмотреть внимательно, то мы увидим, что основой меню является ненумерованный список (как я и говорил). В отдельные пунты меню вложены другие списки (это субменюшки, которые будут распахиваться при наведении курсора мыши). Оборачивающие <div id=”shade#”> нам нужны для размещения теней от меню. Тут я использовал совсем простое визуальное оформление, просто чтобы донести идею. Естественно, ваша фантазия может быть безграничной:-)

Итак, после того, как мы сделаем само меню, нам необходимо запустить страницу в браузере и замерить высоту всех блоков экранной линейкой (скачать можно тут) – это пригодится нам для построения “теней”, так как надо будет делать тень четко под размер блока.

Теперь откроем Photoshop и создадим новый файл высотой в 1 пиксель, а шириной равной ширине блоков нашего меню. Зальем его цветом и настроим прозрачность. А затем сохраним как png24 (с альфа-каналом). Это будет бэкграунд всех наших пунктов меню. Теперь создадим файлы по количеству блоков, а по ширине и высоте равные соответствующим блокам (вы ведь замерили высоту блоков?:-) ). Зальем их желаемым цветом, настроим прозрачность и мягкой стеркой дадим растушевку на краях, чтобы получились мягкие переходы. У меня вышло вот так:
bg_s
Тени тоже готовы. Теперь нам осталось задать css-стили:

#shad {
background: url(./bg_s.png) bottom right no-repeat;
padding: 0;
width: 157px;
height: 107px;
}

#shad1 {
background: url(./bg_s.png) bottom right no-repeat;
padding: 0;
width: 157px;
height: 107px;
}

#shad2 {
background: url(./bg_s1.png) bottom right no-repeat;
padding: 0;
width: 157px;
height: 83px;
}

#shad3 {
background: url(./bg_s1.png) bottom right no-repeat;
padding: 0;
width: 157px;
height: 83px;
}

ul {
margin: 0;
padding: 0;
list-style: none;
width: 150px;
border-bottom: 1px solid #00ff3c;
}

ul li {
position: relative;
}

li ul {
position: absolute;
left: 0px;
top: 0;
display: none;
}

li div {
position: absolute;
left: 149px;
top: 0;
display: none;
}

ul li a {
display: block;
text-decoration: none;
color: #229922;
font-weight: bold;
background: url(./bg.png);
padding: 5px;
border: 1px solid #00ff3c;
border-bottom: 0;
}

li:hover div {
display: block;
}

li:hover ul {
display: block;
}

Итак, по пунктам. В моей стилевой таблице для начала заданы контейнеры, которые будут вмещать тени. Потом, мы сбрасываем на всех ненумерованных списках внешние и внутренние отступы, буллеты, задаем нижнюю границу нужного цвета. Далее, мы даем всем элементам списка position:relative, чтобы список вложенный в пункт вышестоящего списка наследовал его позицию в пространстве. Затем, спискам, вложенным в вышестоящий элемент списка даюм абсолютную позицию, чтобы они не раздвигали список-родитель, и задаем им позицию относительно вмещающего элемента списка. А также скрываем их пока от любопытных глаз:-) Следующим шагом мы задаем позиционирование контейнерам div, вложенным в вышестоящий пункт списка, и тоже скрываем их (мы ведь не хотим, чтобы тени ото всех подменю постоянно мозолили нам глаза?:-) ). Настраиваем стиль ссылок. Даем отступы, границы и прописываем наш полупрозрачный фон. И, наконец, говорим браузеру, что при наведении курсора мыши на элемент списка нам хотелось бы увидеть все вложенные контейнеры. И, вуаля. Наше меню работает.

Готовый пример можно скачать, и поковырять самостоятельно. Успехов!

UPD:
А вот еще по просьбам трудящихся выкладываю вариант этой же менюшки, но горизонтального расположения. Подменю выпадают вниз.

Трюк со ссылкой – показываем картинку.

веб-дизайнер, January 27, 2009

Достаточно часто в процессе веб-разработки дизайнеру приходится сталкиваться с ситуацией, когда необходимо “оживить” ссылку, на которую наводится курсор. Тому, как это сделать без помощи флеша и джава-скриптов посвящен сегодняшний рассказ.

Для начала – ссылки на сайты (c-action, Шаг за горизонт), где подобный метод реализован достаточно хорошо. Безо всякого Flash и  Java Script мы легко можем сделать интерфейс сайта более динамичным.

Суть метода заключается в следующем:  мы добавляем в ссылку тег <span></span>, содержащий нужную нам графику. И, до поры, до времен прячем его. А при наведении курсора на ссылку делаем видимым. Абсолютное позиционирование контейнера позволяет нам перемещать графику в любое место пространства. Если проявить фантазию, поле для деятельности – безгранично.

Подробный листинг (на примере “Шага за горизонт”):

HTML:

&lt;span id=”item1″>&lt;img src=”d1.jpg” alt=”” />&lt;/span>

CSS:

a span {
display: none;
}

a:hover span {
display: inline;
position: absolute;
}

а позиционирование элементов назначается отдельно, по id:

#item1 {
left: 495px;
top: 100px;
}

Все достаточно просто, не правда ли?;-)

————————————-

Позиционирование элементов на JavaScript.

Вячеслав Гринин, January 13, 2009

Сегодня я расскажу о том, как правильно позиционировать элементы страницы друг относительно друга.
Зачем это нужно? Например, чтобы создать красивый выпадающий список. Сегодня мы зададимся целью создать некий пользовательский комбо-бокс. И стандартные возможности HTML нас не устраивают. То есть, мы хотим получить нечто более сложное, чем вот это.

<select>
<option>Item 1</option>
<option>Item 2</option>
<option>Item 3</option>
</select>

А получить хотели бы нечто вроде этого:

<input type=’text’ style=’width: 100px;’ id=’textbox1’/>
<div style=’border: 1px solid #072; background-color: #59E75D; width: 100px;’ id=’list1′>
<ul>
<li><a href=’#’>Item 1</a></li>
<li><a href=’#’>Item 2</a></li>
<li><a href=’#’>Item 3</a></li>
</ul>

То есть мы хотим отпозиционировать DIV так, чтобы он прикрепился к одному из углов другого элемента на странице. 

Вообще, для позиционирования элемента в координатах, заданных своими величинами (X, Y) подойдет вот такая функция:

function setPosXY(obj,x,y) {
  if(obj) {
    obj.style.position=’absolute’;
    obj.style.left=x+’px’;
    obj.style.top=y+’px’;
  }
}

Эта функция проста и особых пояснений не требует. Осталось только правильно определить координаты того элемента(E1), относительно которого хочется спозиционировать заданный элемент(E2), да еще и в соответствии с тем, к какому именно углу E1 будет пристыкован E2.  Углов у любого прямоугольника всего 4. Соответственно и вариантов позиционирования будет 4.

Вот они:

Функция getBounds определяет параметры left, top, width, height объекта. Цикл while нужен для того, чтобы определить абсолютные координаты объекта относительно контейнера <body>.

function getBounds(obj){
  var w=obj.offsetWidth;
  var h=obj.offsetHeight;
  var x=y=0;
  while(obj){
    x+=obj.offsetLeft;
    y+=obj.offsetTop;
    obj=obj.offsetParent;
  }
  return{x:x,y:y,width:w,height:h};
}

 Ну а вот и сама функция позиционирования:

function setPos(anc_id,obj_id,corner,margin){
// anc_id – id элемента, относительно которого будем позиционировать
// obj_id – id элемента, который будем позиционировать
// corner – номер угла (смотрите Рис.1)
// margin – отступ между элементами, чтобы они не “слипались”
  if(!corner)corner=1;
  var obj=document.getElementById(obj_id);
  var anc=document.getElementById(anc_id);
  if(!obj||!anc) return;
  var b=getBounds(anc);
  var c=getBounds(obj);
  var xs=0,ys=0; // координаты left и top родительского элемента (на случай, если кто-то из родителей абсолютно позиционирован)
  var par=obj;
  for(var i=0;i<50;i++){
    par=par.parentNode;
    if(!par||par.tagName==’BODY’) break;
    var s=getCurrentStyle(par);
    if(par.tagName==’DIV’&&s&&s.position==’absolute’){
      var p=getBounds(par);
      xs+=p.x
      ys+=p.y;
      break;
    }
  }
  var xc=0,yc=0; // Дополнительные отступы, учитывающие номер угла
  switch(corner){
    case 2:
      yc=-c.height-b.height;
      break;
    case 3:
      yc=-c.height-b.height;
      xc=-c.width;
      break;
    case 4:
      xc=-c.width+b.width;
      break;
  }
  var xm=0;ym=0; // Дополнительные отступы, учитывающие параметр margin
  if(margin){
    xm=margin.x;
    ym=margin.y;
  }
  SetPosXY(obj,b.x-xs+xc+xm,b.y+b.height-ys+yc+ym);
}

И чуть не забыл, функция getCurrentStyle нужна, чтобы кроссбаузерно определить текущий стиль элемента:

function getCurrentStyle(el){
  if(!el) return null;
  var s=el.currentStyle; 
  if(!s) s=document.defaultView.getComputedStyle(el,null); // Для FireFox
  return s;
}

А вот здесь находится весь скрипт.  Пользуйтесь на здоровье.
Ну а вызов этой функции может выглядеть так:

setPos(‘textbox1′,’list1’,1,{‘x’:2, ‘y’:2});

————————————-

Поиск по блогу:
Подписаться:
Популярные:
Облако тегов:
Разное:
Счетчик: