Перетяжка, Премия ТПрогер, 13.11
Перетяжка, Премия ТПрогер, 13.11
Перетяжка, Премия ТПрогер, 13.11

Man or Boy test в CSS: три способа сверстать бургер-меню

В сфере построения компиляторов есть "Man or Boy test", предложенный Дональдом Кнутом для проверки компиляторов. Я решил придумать аналогичный простой тест в области CSS! Проверь свой уровень навыков в вёрстке на примере бургерного меню!

188 открытий2К показов
Man or Boy test в CSS: три способа сверстать бургер-меню

Всем привет!

Меня зовут Рамазан, и я люблю создавать всякие интересности в вебе.

В этой статье мы посмотрим на тест "Man or boy", который покажет уровень скилла Frontend-разработчика в вёрстке. К слову, название этого теста - отсылка к "Man or boy test", который однажды предложил Дональд Кнут в сфере разработки компиляторов.

В нашей же статье мы покажем три уровня скилла в вёрстке: Man, Boy и промежуточный Teen на всем известном примере. И сейчас это будет вёрстка бургерного меню. Да, то, как сделан этот популярный элемент в интерфейсе, может многое сказать об уровне разработчика!

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

Ну что, поехали!

Начальные настройки

Представим, что мы создаём мобильное меню и хотим сделать классическую кнопку для его открытия и закрытия. Обычно роль такой кнопки играет "бургерное меню" (далее также - бургер, меню), состоящее из трёх горизонтальных толстых линий. Примерно вот такого результата мы хотим в итоге добиться:

Man or Boy test в CSS: три способа сверстать бургер-меню 1
Ожидаемый результат

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

			<div class="D-f Plcc-c Plci-c H100vh -BtnColor#333 -BurgerColor#f1f1f1">
</div>
		

Вот CSS, который будет сгенерирован из этой разметки:

			.D-f {
 display: flex;
}
.Plcc-c {
 place-content: center;
}
.Plci-c {
 place-items: center;
}
.H100vh {
 height: 100vh;
}
.-BtnColor\#333 {
 --ml-btnColor: #333;
}
.-BurgerColor\#f1f1f1 {
 --ml-burgerColor: #f1f1f1;
}
		

Дальше добавим саму кнопку, в которой и будет находиться наш бургер.

			<div class="D-f Plcc-c;c Plci-c;c H100vh
-BtnColor#333 -BurgerColor#f1f1f1">
  <button class="D W14u Bdrd2u Bgc-$btnColor">
  </button>
</div>
		

CSS, который добавится:

			.D {
 display: block;
}
.W14u {
 width: 3.5rem;
}
.Bdrd2u {
 border-radius: 0.5rem;
}
.Bgc-\$btnColor {
 background-color: var(--ml-btnColor);
}
		

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

Boy

Если разработчик только начинает свой увлекательный путь в мире CSS, то он наверняка не захочет сильно напрягаться над каким-то бургерным меню. Поэтому, чтобы сэкономить время, он просто найдёт Unicode-символ бургерного меню и вставит его прямо в кнопку. Может быть он ещё добавит какие-нибудь стили, чтобы всё выглядело хорошо (по возможности):

			<button class="D W14u Bdrd2u Bgc-$btnColor Fns10u Pb1u C-$burgerColor">
   ☰
</button>
		

CSS:

			.Fns10u {
 font-size: 2.5rem;
}
.Pb1u {
 padding-bottom: 0.25rem;
}
.C-\$burgerColor {
 color: var( --ml-burgerColor);
}
		

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

Teen

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

			<button class="-Sz14u Bdrd2u Bgc-$btnColor P3u D-f Fld-c Jc-sb Ai-c">
 <div class="H15p W100p Bgc-$burgerColor"></div>
 <div class="H15p W100p Bgc-$burgerColor"></div>
 <div class="H15p W100p Bgc-$burgerColor"></div>
</button>
		

CSS:

			/* extra styles for the button */
.-Sz14u {
 width: 3.5rem;
 height: 3.5rem;
}
.P3u {
 padding: 0.75rem;
}
.D-f {
 display: flex;
}
.Fld-c {
 flex-direction: column;
}
.Jc-sb {
 justify-content: space-between;
}
.Ai-c {
 align-items: center;
}
/* styles for the lines */
.H15p {
 height: 15%;
}
.W100p {
 width: 100%;
}
.Bgc-\$burgerColor {
 background-color: var( --ml-burgerColor);
}
		

То есть мы просто делаем нашу кнопку `flex`-контейнером, а `div`-ы внутри неё равномерно распределяем по пространству. Вот, в принципе, и всё основное об этом способе. Стоит ещё раз подчеркнуть, что он уже позволяет сделать наше меню анимированным - в этом у нас полная свобода.

Man

Но, если перед нами настоящий профессионал, познавший многие тонкости вёрстки, его уже могут не устроить три одинаковых `div`-а в разметке. Они занимают место, а большого смысла не несут. И тогда он может вспомнить, что существуют такие элементы, которые задаются исключительно CSS-стилями - псевдоэлементы `::after` и `::before`. А ему здесь хватит даже одного!

			<button class="-Sz14u Bdrd2u Bgc-$btnColor P3u D-f Fld-c Jc-fs Ai-c
   Ct_af D_af H1u_af W100p_af Bgc-$burgerColor_af
   Bxsd0;3u;0;0;$burgerColor,0;6u;0;0;$burgerColor_af">
   <span class="-D-vh"> Menu </span>
</button>
		

Здесь мы изменили значение `justify-content` для кнопки, а также добавили стили для псевдоэлемента `::after`. Такими будут сгенерированные CSS-стили:

			/* extra style for the button itself */
.Jc-fs {
 justify-content: flex-start;
}


/* styles for the button::after */ {
.Ct_af::after {
 content: '';
}
.D_af::after {
 display: block;
}
.H1u_af::after {
 height: 0.25rem;
}
.W100p_af::after {
 width: 100%;
}
.Bgc-\$burgerColor_af::after {
 background-color: var( - ml-burgerColor);
}
.Bxsd0\;3u\;0\;0\;\$burgerColor\,0\;6u\;0\;0\;\$burgerColor_af::after {
 box-shadow: 0px 0.75rem 0px 0px var( - ml-burgerColor), 0px 1.5rem 0px 0px var( - ml-burgerColor);
}
.Bgc-red_h\,fv:hover, .Bgc-red_h\,fv:focus-visible {
 background-color: red;
}
/* styles for the caption */
.-D-vh {
 position: absolute;
 width: 1px;
 height: 1px;
 margin: -1px;
 padding: 0;
 overflow: hidden;
 white-space: nowrap;
 border: 0;
 clip: rect(0 0 0 0);
}
		

Это работает примерно так:

- мы задаём один псевдоэлемент у нашей кнопки, располагаем его нужным образом;

- у этого псевдоэлемента создаём две тени, расположенные с необходимым интервалом;

- мы задали скрытую подпись у кнопки, потому что настоящий профессионал должен заботиться и о доступности контента.

Вот и всё - не так уж сложно было, не правда ли? Но зато как элегантно! При желании здесь можно делать и хорошие анимации, по-разному двигая тени и окрашивая их.

Итоги

Я рад, что ты дочитал мою небольшую статью до конца. Надеюсь, что она была для тебя полезна и помогла прокачать твои навыки! В будущем я планирую выпустить ещё несколько статей на тему вёрстки. Буду рад, если ты вернёшься и почитаешь их :)

Успехов в этом увлекательном пути разработки!

Следите за новыми постами
Следите за новыми постами по любимым темам
188 открытий2К показов