Создаем вертикальное меню на CSS

Reading time ~6 minutes

Продолжаем изучение CSS и сегодня приступим к построению вертикального меню.

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

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

Механизм действия и построения такого меню основан на одном единственном CSS-свойстве - display, а точнее на его значениях - display: block и display: none.

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

Такая навигация называется меню-аккордеон и принцип его создания будет рассмотрен позже.

C чего же мы начнем? С построения обычного маркированного списка, пунктами которого будут ссылки. Списку зададим класс с именем menu, так как он нам понадобиться в дальнейшем:

<ul class="menu">
  <li>
    <a href="#">Punkt 1</a>
  </li>
  <li>
    <a href="#">Punkt 2</a>
  </li>
  <li>
    <a href="#">Punkt 3</a>
  </li>
  <li>
    <a href="#">Punkt 4</a>
  </li>
  <li>
    <a href="#">Punkt 5</a>
  </li>
</ul>

Созданное только что меню будет внешним, а внутри него (точнее внутри его пунктов) мы поместим еще одно меню. Получиться одно меню, вложенное в другое (помните уроки HTML?).

То есть, у нас есть пять пунктов внешнего меню - вот мы и вложим в каждый из них еще одно меню, перед ссылкой. Ссылка будет исполнять роль переключателя, который будет переводить значение свойства display из none в block и наоборот.

В итоге получиться пять подменю, для каждого из которых мы пропишем один класс - sub-menu. Этот класс нам также потребуется в дальнейшем:

<ul class="menu">
  <li>
    <a href="#">Punkt 1</a>
        <ul class="sub-menu">
      <li>
        <a href="#">Punkt 1-1</a>
      </li>
      <li>
        <a href="#">Punkt 1-2</a>
      </li>
      <li>
        <a href="#">Punkt 1-3</a>
      </li>
    </ul>
  </li>
  <li>
    <a href="#">Punkt 2</a>
        <ul class="sub-menu">
      <li>
        <a href="#">Punkt 2-1</a>
      </li>
      <li>
        <a href="#">Punkt 2-2</a>
      </li>
      <li>
        <a href="#">Punkt 2-3</a>
      </li>
    </ul>
  </li>
  <li>
    <a href="#">Punkt 3</a>
        <ul class="sub-menu">
      <li>
        <a href="#">Punkt 3-1</a>
      </li>
      <li>
        <a href="#">Punkt 3-2</a>
      </li>
      <li>
        <a href="#">Punkt 3-3</a>
      </li>
    </ul>
  </li>
  <li>
    <a href="#">Punkt 4</a>
        <ul class="sub-menu">
      <li>
        <a href="#">Punkt 4-1</a>
      </li>
      <li>
        <a href="#">Punkt 4-2</a>
      </li>
      <li>
        <a href="#">Punkt 4-3</a>
      </li>
    </ul>
  </li>
  <li>
    <a href="#">Punkt 5</a>
        <ul class="sub-menu">
      <li>
        <a href="#">Punkt 5-1</a>
      </li>
      <li>
        <a href="#">Punkt 5-2</a>
      </li>
      <li>
        <a href="#">Punkt 5-3</a>
      </li>
    </ul>
  </li>
</ul>

Все - каркас будущего вертикального меню готов и больше мы его трогать не будем. Остальные действия будем выполнять только с помощью CSS. Для начала создадим базовые стили, чтобы придать нашему меню хоть какой-то вид:

*{
  margin: 0;
  padding: 0;
}

a{
  text-decoration: none;
}

ul{
  list-style-type: none;
}

.menu{
  margin: 30px 0 0 30px;
  width: 100px;
}

Здесь мы обнуляем margin и padding для всех элементов, в том числе и ul; убираем маркер у пунктов меню; убираем подчеркивание у ссылок.

Для внешнего списка с классом menu задаем отступ сверху и слева, чтобы не прилипал к границам окна браузера и устанавливаем фиксированную ширину в 100px.

Дальше форматируем пункты меню:

.menu li{
    position: relative;
    line-height: 20px;
    background-color: #ccc;
    margin-bottom: 1px;
  }

Ставим высоту каждого элемента li равной 20px и выравниваем текст внутри него по центру вертикали; задаем фоновый цвет для них же, чтобы можно было различать каждый из пунктов на фоне окна браузера; делаем нижний margin в 1px, чтобы элементы li не сливались между собой и были похожи на пункты меню.

Последний шаг - устанавливаем для li относительное позиционирование, так как в дальнейшем будем размещать подменю относительно этого элемента.

Далее чисто косметические правила для ссылок, находящихся внутри внешнего меню - размер шрифта (кегль) и цвет текста:

.menu li a{
  font-size: 16px;
  color: #000;
}

Теперь приступаем к самому интересному - стилизации подменю. Для начала зададим его ширину (пусть будет чуть меньше ширины внешнего списка):

.sub-menu{
  width: 90px;
}

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

И самое главное - скроем его отображение в браузере через правило display: none. В результате код будет выглядеть следующим образом:

.sub-menu{
  width: 90px;
  position: absolute;
  left: 100px;
  top: 0;
  display: none;
}

Немного стилизуем пункты меню и ссылки в подменю. Для каждого пункта подменю устанавливаем цвет фона, чтобы отличать подменю от основного меню. И цвет ссылок по той же причине:

.sub-menu li{
  background-color: #aaa;
}
  .sub-menu li a{
    color: #fff;
  }

Заключительный код, который заставляет наше меню работать именно так, как задумано. То есть, этим мы говорим браузеру присвоить свойству display значение block при наведении мыши на ссылку во внешнем списке:

.menu li:hover .sub-menu{
  display: block;
}

В результате подменю отобразиться (браузер сгенерирует его). Изначально в коде было прописано для него display: none. То есть, для браузера такого подменю не существовало и в DOM-модели документа элемент ul с классом sub-menu отсутствовал.

Так как этому подменю задано абсолютное позиционирование со смещением вправо на 100px и вверх на 0px, то оно поместиться точно справа вверху от своего родителя - пункта меню внешнего списка.

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

Вертикальное меню на CSS

И меню, когда наведена мышка на один из пунктов меню и справа появляется подменю, соответствующее этому пункту:

Вертикальное меню на CSS с подменю

На этом все.


Ellipsis для массива в Go

Токен `...` **используется для массивов** и он **имеет огромный смысл** именно потому, что массивы в Go имеют фиксированную длину.Дело в ...… Continue reading