Классическое древовидное меню, всем нам хорошо известное, часто используется во всем мире, и оно определенно может быть полезно при правильном использовании. В сети масса различных примеров подобных менюшек, но во всех них используется JavaScript. Не удовлетворившись ни с одним из таких решений я попробовал сделать это на чистом CSS. Ниже вы можете увидеть, что получилось в итоге.
Как вы можете видеть структура представляет собой список, с вложенным label и чекбоксом, по клику на который меню будет раскрываться.
li input{ position:absolute; left:0; margin-left:0;
opacity:0; z-index:2; cursor:pointer; height:1em; width:1em; top:0; }
li label{ background:url(img)15px1pxno-repeat; cursor:pointer; display:block; padding-left:37px; }
Чтобы установить input и label в правильном визуальном порядке, я задал абсолютное позиционирование для input и задал отступ слева для label
li input + ol { background:url(toggle-small-expand.png)40px0no-repeat; margin:-0.938em00-44px;/* 15px */ display:block; height:1em; }
Чтобы правильно расположить ol, я использую отрицательный отступ(margin-left: -0.938em 0 0 -44px), чтобы разместить его таким образом, что он будет находиться рядом с label и под невидимым чекбоксом.
li input + ol > li { display:none; margin-left:-14px !important; padding-left:1px; }
Чтобы скрыть подпапки, чтобы они не появлялись, когда родительская папка свернута, я использовал display: none, это также не позволяет перемещению с помощью клавиатуры по свернутым пунктам меню.
li label { background:url(folder.png)15px1pxno-repeat; }
li.file a { background:url(document.png)0-1pxno-repeat; color:#fff; padding-left:21px; text-decoration:none; display:block; }
Чтобы было различие между папками и файлами, я применил разные фоновые изображения к label и к ссылкам в списке файлов (li.file a).
li { position:relative; margin-left:-15px; list-style:none; }
li.file{ margin-left:-1px !important; }
К элементам со списком папок я применяю большее отрицательное поле, таким образом папки выстраиваются в линию с любым из пунктов-файлов, а для пунктов-файлов я сбрасываю левое поле.
Изменение иконки в зависимости от расширения
С помощью некоторых CSS3 атрибутов селекторов мы можем определить, какое расширение имеет файл, и изменить значок соответственно.
* = будет соответствовать подстроке, которая содержит .pdf или .html где угодно в пределах атрибута, и если у ссылки есть соответствующая строка, мы можем установить соответствующее изображение расширению файла. У способа есть небольшой недостаток, он будет искать соответствие по всей строке и если, например, Ваш файл называется file.html.pdf, то он будет соответствовать обоим типам файлов, и к пункту в этом случае будет применено правило, которое будет иметь более высокую специфику CSS.
Атрибуты чекбоксов
В демонстрационном примере по умолчанию первая папка открыта, это сделано благодаря добавлению атрибут checked к чекбоксу.
Мы также можем добавить disabled атрибут к чекбоксу, чтобы не позволять пользователю открыть папку, поскольку input ни не может быть отмечен.
Наконец, использование комбинации checked и disabled позволит нам показывать под папки и файлы, но при этом не позволяет пользователю закрывать папку верхнего уровня.
Кроссбраузерность
Данное меню будет работать в любом браузере, который поддерживает CSS3-селекторы. Оно было успешно протестировано в следующих браузерах: