ArtShok. Сайтостроение и немного SEO

Уроки и примеры по CSS, jQuery. Советы по монетизации и продвижению сайтов

6 сентября 2008

Как сделать древовидный список с помощью CSS


Сегодня мы рассмотрим урок по созданию древовидного списка, каждый из пунктов которого соединяется линиями.

Древовидный список методами CSS, оформление списка с помощью CSS

Если не засорять код чем-то лишним, то в идеале он будет выглядеть следующим образом:

[php]
<ul class="tree">
<li>Продукты
<ul>
<li>Молочные
<ul>
<li>Молоко</li>
<li>Кефир</li>
</ul>
</li>
.
.
.
</ul>
[/php]

По сути, это простой многоуровневый список. Единственная вещь, превращающая его его в “дерево” - класс tree, который мы присвоили <ul>. Без него список выглядит самым обычным образом:

  • Продукты
    • Молочные
      • Молоко
      • Ряженка
      • Кефир
    • Овощи
    • Фрукты
  • Столовые приборы
    • Ложки
      • Суповые
      • Десертные
      • Чайные
    • Вилки

Избавляемся от “пуль”

Первое, что мы теперь должны сделать, это избавиться от так называемых “пуль” - точки, квадратики, кружочки и пр., расположенных напротив позиций списка. Для этого присваиваем list-style-type значение none.

[css]
ul.tree, ul.tree ul {list-style-type: none;}
[/css]

Рисуем вертильные линии

Теперь необходимо нарисовать вертикальную прямую напротив каждого из пункта вне зависимости от уровня вложения. Для этого используем следующую картинку (ширина - 1px, высота - 10px):

Древовидный список методами CSS, оформление списка с помощью CSS

vline.png

Прописываем ее фоном для списка <ul> и добавляем значение repeat-y, теперь картинка будет повторяться по оси y, тем самым создавая вертикальную прямую по высоте всего спика. Добавляем значение для margin и padding к <li>, тем самым красиво форматируя будущую структуру списка.

[css]
ul.tree, ul.tree ul {
list-style-type: none;
background: url(vline.png) repeat-y;
margin: 0;
padding: 0;
}

ul.tree ul {
margin-left: 10px;
}<strong>

</strong>ul.tree li {
margin: 0;
padding: 0 12px;
}
[/css]

Объединяем

Используем фоном картинку с Т-образной линией для каждого из пунктов.

Древовидный список методами CSS, оформление списка с помощью CSS

node.png

Устанавливаем значение line-height, равное высоте картинки. Для текса определяем цвет #369 и выделяем жирным bold.

[css]
ul.tree, ul.tree ul {
list-style-type: none;
background: url(vline.png) repeat-y;
margin: 0;
padding: 0;
}

ul.tree ul {
margin-left: 10px;
}

ul.tree li {
margin: 0;
padding: 0 12px;
line-height: 20px;
background: url(node.png) no-repeat;
color: #369;
font-weight: bold;
}
[/css]

И последнее:)

Как видим, для последнего пункта требуется специальный стиль. Во-первых, в качестве фона будем использовать другую картинку:

Древовидный список методами CSS, оформление списка с помощью CSS

lastnode.png

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

[css]
ul.tree, ul.tree ul {
list-style-type: none;
background: url(vline.png) repeat-y;
margin: 0;
padding: 0;
}

ul.tree ul {
margin-left: 10px;
}

ul.tree li {
margin: 0;
padding: 0 12px;
line-height: 20px;
background: url(node.png) no-repeat;
color: #369;
font-weight: bold;
}

ul.tree li.last {
background: #fff url(lastnode.png) no-repeat;
}
[/css]

Браузер не знает, какая из записей последняя, поэтому прописываем класс last там, где это необходимо:

[css]
<ul class="tree">
<li>Animals
<ul>
<li>Birds</li>
<li>Mammals
<ul>
<li>Elephant</li>
<li<strong> </strong>class="last">Mouse</li>
</ul>
</li>
<li<strong> </strong>class="last">Reptiles</li>
.
.
.
</ul>
[/css]

…если лень - используйте JavaScript, который сделает все сам:

[php]
<script type="text/javascript">
window.onload = function () {
var tree = document.getElementById("tree");
var lists = [ tree ];

for (var i = 0; i < tree.getElementsByTagName("ul").length; i++)
lists[lists.length] = tree.getElementsByTagName("ul")[i];

for (var i = 0; i < lists.length; i++) {
var item = lists[i].lastChild;

while (!item.tagName || item.tagName.toLowerCase() != "li")
item = item.previousSibling;

item.className += " last";
}
};
</script>
.
.
.
<ul class="tree"<strong> </strong>id="tree">
<li>Animals
<ul>
<li>Birds</li>
<li>Mammals
<ul>
<li>Elephant</li>
<li>Mouse</li>
</ul>
</li>
.
.
.
</ul>
[/php]

Конечно, каждый раз добавлять класс last - это не лучший выход. Фактически, есть изящное решение данной проблемы - псевдо-класс :last-child. Чтобы использовать его, присваиваем данный селектор к классу last:

[php]
ul.tree li<strong>:</strong>last-child {
background: #fff url(lastnode.png) no-repeat;
}
[/php]
К сожалению, данный псевдо-класс используется только в CSS3 и лишь некоторые браузеры его поддерживают.

Скачать урок

*Вольный перевод статьи “Turning Lists into Trees”

Спасибо за добавление статьи в:



Комментарии к этой записи


  1. # 1 Мимопробегавший (1)

    А что ссылку на оригинал - http://odyniec.net/articles/turning-lists-into-trees/ не дали-то?

    [Ответить]


  2. О… Спасибо за ссылку! А то совсем из памяти выпало, где пример был.

    [Ответить]


  3. Довольно-таки познавательно.

    [Ответить]


  4. Блин, зашел по запросу Древовидные комментарии (( Ты случайно не знаешь как их сделать, а то плагин у меня глючит (урлов нет) ?

    [Ответить]

    ArtShok:

    Так вроде в последних версиях WordPress была поддержка древовидных комментов по умолчанию. Нет? Тока один плаггин знаю, пока материала больше не попадалось на глаза. Но если найду - свисну.

    [Ответить]

    Санёк:

    Там эта опция работает только в стандартной теме. Другие нужно как-то переделывать. У меня стоит плагин для древовидных каментов, но почему-то ссылки комментаторов вижу только я - другие ссылок не видят(((

    [Ответить]

    Санёк:

    Кстати, у тя что за плагин? Как у тебя реализованы древовидные комментарии?

    [Ответить]

    ArtShok:

    У меня Wordpress Thread Comment стоит

    [Ответить]

    Санёк:

    У меня тоже он, но бложек с ним не дружит ((


  5. А что для первого элемента не задали стиль?

    ul.tree > li:first-child {
    background: #FFF url(lastnode.png) no-repeat;
    }

    (если считать что браузер у нас знаком с css3)

    [Ответить]

Оставить комментарий или два