TGViewer
WebDev+ | Веб-разработка WebDev+ | Веб-разработка @webdev_plus · 7.9K subscribers
Post #1145 1.1K
Оргструктуры, дерево файлов, турнирные сетки — всё на чистом CSS. Без canvas, без SVG, без JavaScript. Только flexbox и псевдоэлементы.

Разбираем по шагам. Начнём с базового дерева слева направо, где пару десятков строк CSS превращают вот это…(1 photo) во вот это…(2)

HTML — обычные вложенные списки:

<ul class="tree">
<li>
<span>1</span>
<ul>
<li><span>1.1</span></li>
<li><span>1.2</span></li>
</ul>
</li>
</ul>


Задача: превратить это в дерево с соединительными линиями.

Основная механика — flexbox. Каждый <li> становится flex-контейнером:

li {
display: flex;
flex-direction: row;
align-items: center;
}


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

Первая линия: от родителя к дочерним элементам. Ставим её на <ul>, а не на родительский <li>:

ul::before {
content: "";
position: absolute;
left: 0;
top: 50%;
border-top: 1px solid;
width: 2vw;
}


Дальше: линии от каждого ребёнка обратно к родителю. Та же техника, но на <li>:

li::before {
content: "";
position: absolute;
left: 0;
top: 50%;
border-top: 1px solid;
width: 2vw;
}


Проблема: корневой элемент тоже получает линию, хотя родителя у него нет. Чиним через селектор прямого потомка:

.tree > li {
padding-left: 0;

&::before, &::after {
display: none;
}
}


Самое тонкое место — вертикальные линии между соседями. Нужны разные высоты:

первый ребёнок — нижняя половина
последний — верхняя половина
все промежуточные — целая линия

Используем ::after:

li::after {
content: "";
position: absolute;
left: 0;
border-left: 1px solid;
}

li:first-of-type::after { height: 50%; bottom: 0; }
li:last-of-type::after { height: 50%; top: 0; }
li:not(:first-of-type):not(:last-of-type)::after {
height: 100%;
}


78 строк CSS — и дерево готово.

Но это только горизонтальный вариант слева направо.

@WebDev_Plus
More from @webdev_plus
  1. Oct 8, 2026Набор полезных пользовательских CSS-функций, который работает на новой нативной директиве…
  2. Oct 8, 2026Как работают очереди в контексте HTTP-запросов Разбираются основные стратегии очередей: FI…
  3. Oct 7, 2026Разработчики Next.js: добавьте эти 4 строки в ваш .vscode/settings.json, чтобы сразу прока…
  4. Oct 7, 2026Полезное расширение для Chrome «Responsive Viewer» Помогает веб-разработчикам и дизайнерам…
  5. Oct 6, 2026Laravel / PHP: как предпочитаете отправлять письма — описывать их прямо в месте вызова или…
  6. Oct 6, 2026Этот HTML-косяк непростителен. Не использовать атрибут inputmode в элементах input — серьё…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →