Древовидный список | HTML

Простой вложенный список

  • Сайт
    • Блог
      • HTML
      • CSS
      • JavaScript
    • Контакты
<ul class="treeCSS">
  <li>Сайт
    <ul>
      <li>Блог
        <ul>
          <li>HTML
          <li>CSS
          <li>JavaScript
        </ul>
      <li>Контакты
    </ul>
</ul>

Статья по теме: Древовидный нумерованный список

Древовидное меню, пункты которого объединяются линиями

  • Сайт
    • Блог
      • HTML
      • CSS
      • JavaScript
    • Контакты
<style>
.treeCSS, 
.treeCSS ul,
.treeCSS li {
  margin: 0;
  padding: 0;
  line-height: 1;
  list-style: none;
}
.treeCSS ul {
  margin: 0 0 0 .5em; /* вести линию вниз где-то с полбуквы родителя */
}
.treeCSS > li:not(:only-child),
.treeCSS li li {
  position: relative;
  padding: .2em 0 0 1.2em; /* отступ до текста; для раскрывающегося списка в ряде случаев (в Хроме есть баг) padding-top (.2em) лучше указывать в px */
}
.treeCSS li:not(:last-child) {
  border-left: 1px solid #ccc; /* толщина, цвет и стиль (вместо сплошной пунктирная или точечная) вертикальной линии */
}
.treeCSS li li:before,
.treeCSS > li:not(:only-child):before { /* горизонтальная линия */
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 1.1em; /* не более отступа до текста (1.2em) */
  height: .7em; /* начинается приблизительно с половины высоты буквы (.5em + .2em) */
  border-bottom: 1px solid #ccc;
}
.treeCSS li:last-child:before { /* вертикальная линия последнего пункта в каждом списке */
  width: calc(1.1em - 1px); /* для перфекционистов */
  border-left: 1px solid #ccc;
}
</style>

Древовидный раскрывающийся список с JavaScript

  • Сайт
    • Блог
      • HTML
      • CSS
      • JavaScript
    • Контакты
<!-- К предыдущему коду добавить: -->

<style>
.treeCSS .drop {
  position: absolute;
  left: -.5em;
  top: .4em; /* .2em (font-size: 80%;) + .2em (padding из .treeCSS li li) */
  width: .9em;
  height: .9em;
  line-height: .9em;
  text-align: center;
  background: #fff;
  font-size: 80%;
  cursor: pointer;
}
.treeCSS li:last-child > .drop {
  margin-left: 1px;
}
.treeCSS .drop + ul {
  display: none;
}
.treeCSS .dropM + ul {
  display: block;
}
</style>

<script>
(function() {
  var ul = document.querySelectorAll('.treeCSS > li:not(:only-child) ul, .treeCSS ul ul');
  for (var i = 0; i < ul.length; i++) {
    var div = document.createElement('div');
    div.className = 'drop';
    div.innerHTML = '+'; // картинки лучше выравниваются, т.к. символы на одном браузере ровно выглядят, на другом — чуть съезжают 
    ul[i].parentNode.insertBefore(div, ul[i].previousSibling);
    div.onclick = function() {
      this.innerHTML = (this.innerHTML == '+' ? '−' : '+');
      this.className = (this.className == 'drop' ? 'drop dropM' : 'drop');
    }
  }
})();
</script>

Статья по теме: Древовидный список из чебоксов

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

Сайт
Блог
HTML
CSS
JavaScript
Контакты
<!-- Этот вариант мне очень нравится! Открывается благодаря тегу details. На тех браузерах, которые его не поддерживают, посетители увидят развёрнутый список, доступ ко всем уровням меню сохранится -->

<div class="treeHTML">Сайт
  <div>Блог
    <details><summary></summary>
      <div>HTML</div>
      <div>CSS</div>
      <div>JavaScript</div>
    </details>
  </div>
  <div>Контакты</div>
</div>

<style>
.treeHTML {
  line-height: normal;
}
.treeHTML details {
  display: block;
}
.treeHTML div {
  position: relative;
  margin: 0 0 0 .5em;
  padding: 0 0 0 1.2em;
}
.treeHTML div:not(:last-child) { /* необязательно */
  border-left: 1px solid #ccc;
}
.treeHTML div:before { /* необязательно */
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 1.1em;
  height: .5em;
  border-bottom: 1px solid #ccc;
}
.treeHTML div:last-child:before { /* необязательно */
  border-left: 1px solid #ccc;
}
.treeHTML summary { /* стилями можно задать любую форму, например, тот же плюс. Я специально не стала усложнять, чтобы можно было проще разобраться в коде */
  position: absolute;
  top: 0;
  left: 0;
  cursor: pointer;
}
.treeHTML details[open] summary { /* убрать рамку при фокусе */
  outline: none;
}
</style>

Можно без линий:

Сайт
Блог
HTML
CSS
JavaScript
Контакты

Горизонтальная древовидная таблица

  • Сайт
    • Блог
      • HTML
      • CSS
      • JavaScript
    • Контакты
<ul class="tabletree">
  <li>
    <div>Сайт</div>
    <ul>
      <li>
        <div>Блог</div>
        <ul>
          <li><div>HTML</div>
          <li><div>CSS</div>
          <li><div>JavaScript</div>
        </ul>
      <li><div>Контакты</div>
    </ul>
</ul>

<style>
/* Необязательно писать отдельный код для адаптивной вёрстки, т.к. таблица резиновая */
.tabletree {
  margin: 0 !important;
  padding: 0 !important;
  line-height: normal;
  word-wrap: break-word;
  word-break: break-all;
}
.tabletree ul {
  position: relative;
  display: table-cell;
  margin: 0 !important;
  padding: 0 0 0 11px !important;
  vertical-align: middle;
}
.tabletree li {
  display: table;
  position: relative;
  margin: 0 !important;
  padding: 0 !important;
}
.tabletree div {
  display: table-cell;
  vertical-align: middle;
}
/* Линии */
.tabletree ul:before,
.tabletree ul li:after,
.tabletree ul li:not(:last-child):not(:first-child):before {
  content: "";
  position: absolute;
  left: -6px;
  top: 0;
  width: 5px;
  height: 50%;
  border-bottom: 1px solid #999;
}
.tabletree ul:before {
  left: 0;
}
.tabletree ul li:not(:only-child):after {
  border-left: 1px solid #999;
}
.tabletree ul li:not(:only-child):first-child:after {
  top: 50%;
  border-top: 1px solid #999;
  border-bottom-color: transparent;
}
.tabletree ul li:not(:last-child):not(:first-child):before {
  height: 100%;
  border-left: 1px solid #999;
  border-bottom-color: transparent;
}
</style>

Полноценный пример может выглядеть так: Упрощенная таблица «Биологическая систематика»

Вертикальная древовидная таблица

  • Сайт
    • Блог
      • HTML
      • CSS
      • JavaScript
    • Контакты
<!-- См. исходный HTML код -->

<style>
.treeCSS,
.treeCSS ul {
  position: relative;        
  display: table;
  margin: 5px 0 0 0 !important;
  padding: 6px 0 0 0 !important;
  line-height: normal;
  text-align: center;
  word-wrap: break-word;
  word-break: break-all;
}
.treeCSS li {
  position: relative;
  display: table-cell;
}
/* Отступ между пунктами */
.treeCSS li:not(:only-child) {
  padding: 0 .5em;
}
.treeCSS li:last-child {
  padding-right: 0;
}
.treeCSS li:first-child {
  padding-left: 0;
}
/* Линии */
.treeCSS ul:before,
.treeCSS ul li:before,
.treeCSS ul li:after {
  content: "";
  position: absolute;
  top: -5px;
  left: 0;
  width: 50%;
  height: 5px;
  border-right: 1px solid #999;
}
.treeCSS ul:before {
  top: -4px;
}
.treeCSS ul li:not(:only-child):before {
  border-top: 1px solid #999;
}
.treeCSS ul li:not(:only-child):first-child:before {
  right: 0;
  left: auto;
  border-left: 1px solid #999;
  border-right: none;
}
.treeCSS ul li:not(:only-child):first-child:before,
.treeCSS ul li:not(:only-child):last-child:before { /* необязательно, 0.5 взят из свойства padding в селекторе .treeCSS li:not(:only-child) */
  width: calc(50% + .5em/2);
}
.treeCSS ul li:after {
  border: none;
}
.treeCSS ul li:not(:last-child):not(:first-child):after {
  width: 100%;
  border-top: 1px solid #999;
}
</style>
в f t
наверх ↑

2 комментария:

Анонимный
/* стилями можно задать любую форму, например, тот же плюс. Я специально не стала усложнять, чтобы можно было проще разобраться в коде */
Подскажите, пожалуйста, как всётаки, сделать плюсик вместо треугольника?
NMitra
.treeHTML summary {
position: absolute;
left: -.5em;
top: .4em;
width: .9em;
height: .9em;
line-height: .9em;
text-align: center;
background: #fff;
font-size: 80%;
cursor: pointer;
}
.treeHTML summary:before {
content: "+";
}
.treeHTML details[open] summary:before {
content: "-";
}
.treeHTML summary::-webkit-details-marker {
display: none
}

См. http://jsfiddle.net/NMitra/fz6ojqL3/1/
Плохо, что на браузерах, не поддерживающих details плюс тоже видим