Простое адаптивное меню для сайта | CSS

Горизонтальное меню располагается сверху web-страницы, именно там её ожидает увидеть большинство из нас. Когда человек ищет информацию на мобильных телефонах, ему не очень интересно пролистывать навигацию. Поэтому на этих устройствах меню должно быть изначально скрыто и появляться при нажатии на некую кнопку. Повторный клик по кнопке или по другому участку сайта скроет навигацию.

Адаптивное горизонтальное меню на CSS

<style>
nav a, nav:before, nav div:before {
  display: inline-block;
  padding: 10px 0;
  color: #fff;
  text-align: center;
  cursor: pointer; /* курсор в виде руки, обязателен для Opera Mini */
  background: rgb(6,55,82); /* цвет фона кнопки "меню" */
}
nav a {
  width: 25%; /* 4 пункта меню, то есть 100%/4 */
  background: rgb(46,95,122); /* фон пунктов меню */
  text-decoration: none;
}
nav a:hover {
  background: rgb(96,145,172); /* фон пунктов при наведении */
}
@media (max-width: 800px) { /* для экранов, меньше 800px, см про адаптивную вёрстку */
  nav a, nav:before, nav div:before {
    width: 100%; /* пункты меню растягиваются на всю ширину блока */
  }
  nav:before {
    content: "меню";
  }
  nav:focus:before {
    content: none;
  }
  nav:focus div:before {
    content: "свернуть меню";
  }
  nav:not(:focus) div:not(:active) { /* магия кнопки "меню", благодаря чему навигация скрывается/появляется по щелчку */
    display: none;
  }
}
</style>

<!--
tabindex нужен, чтобы срабатывал :focus
-->
<nav tabindex="0"><div tabindex="0"><a href="#">Первый пункт</a><a href="#">Второй пункт</a><a href="#">Третий пункт</a><a href="#">Четвёртый пункт</a></div></nav>

Код основан на этом решении [см. псевдокласс :focus]:

Щелчок по зелёному цвету устанавливает фокус, по красному — снимает. Фокус снимается и при клике вне элемента.


<div tabindex="0" id="raz"><div tabindex="0"></div></div>
в f t
наверх ↑

37 комментариев:

Zzigzz Zzigzz
Не работает на живом телефоне. Полоска с надписью "Меню" не тапается совсем никак. Телефон лыжи p990, если это важно )
NMitra
Да, возможно. pointer-events ещё не все браузеры поддерживают. Пример ниже у вас скорее всего тоже не работает. Можно подкрепить работу JS. Если нужно, сообщите.
NMitra
Вариант с JavaScript (пример http://css.shpargalkablog.ru/2014/04/blog-post_3.html ) :

<style>
nav a {
display: inline-block;
width: 25%; /* 4 пункта меню, то есть 100%/4 */
background: rgb(46,95,122); /* фон пунктов меню */
text-decoration: none;
}
nav a:hover {
background: rgb(96,145,172); /* фон пунктов при наведении */
}
nav a, nav:before {
height: 30px;
line-height: 30px; /* высота пунктов меню, line-height = height */
color: #fff;
text-align: center;
cursor: pointer; /* курсор в виде руки, обязательно для Opera Mini */
}

@media (max-width: 500px) { /* для экранов, меньше 500px, см про адаптивную вёрстку */
nav {
position: relative;
}
nav:before {
content: "меню";
display: block;
background: rgb(6,55,82); /* цвет фона кнопки */
}
nav div {
display: none;
position: absolute; /* меню находится поверх контента */
left: 0;
right: 0;
}
nav a {
width: 100%; /* пункт меню растягивается на всю ширину блока */
}
}
</style>

<nav><div><a href="#">Первый пункт</a><a href="#">Второй пункт</a><a href="#">Третий пункт</a><a href="#">Четвёртый пункт</a></div></nav>

<script>
var nav = document.getElementsByTagName('nav');
mynav();
function mynav() {
var width = window.innerWidth || document.documentElement.clientWidth;
if (500 >= width) {
nav[0].children[0].style.display = 'none';
nav[0].onclick = function(event) {
event = event || window.event;
var t = event.target || event.srcElement;
if (t != this) { return true; }
this.children[0].style.display = this.children[0].style.display === 'none' ? 'block' : 'none';
}
}
}
window.onresize = function() {
mynav();
var width = window.innerWidth || document.documentElement.clientWidth;
if (500 < width) {
nav[0].children[0].style.display = 'block';
}
}
</script>
NMitra
Хм, скрипт можно смело сократить до (сомневаюсь, что на мобильниках стоит IE6):

<script>
var nav = document.getElementsByTagName('nav');
mynav();
function mynav() {
if (500 >= document.documentElement.clientWidth) {
nav[0].children[0].style.display = 'none';
nav[0].onclick = function(e) {
if (e.target != this) { return true; }
this.children[0].style.display = this.children[0].style.display === 'none' ? 'block' : 'none';
}
}
}
window.onresize = function() {
mynav();
if (500 < document.documentElement.clientWidth) {
nav[0].children[0].style.display = 'block';
}
}
</script>
Анонимный
Спасибо за объяснение про tabindex и фокус - очень кстати.
А на смартфоне меню, действительно, не меняет размер и вид.
Думаю, 500px - это маловато. Напишите 800px
NMitra
Написала. Но, по хорошему это значение устанавливается таким образом, чтобы меню не съезжало.
Анонимный
Спасибо, круто. Искал решение чисто на JS. Очень помогло)
NMitra
Я тоже так считаю, мучилась с ним не один день, а кода пшик )))
Анонимный
ывашоыадоывлдолодл щщшощшо гшргшршгр
Золочев Ларк
В Хроме при попытки прокрутить меню вниз- меню сворачивается:( . Как это исправить.
Спасибо.
Золочев Ларк
Из-за чего невозможно нажать на нижние ссылки меню.
NMitra
Попробуйте так http://jsfiddle.net/NMitra/3bn8rhcw/3/
Золочев Ларк
Не получилось. Думаю что проблема зарыта в скрипте
Золочев Ларк
Зарыта
NMitra
Вы на каком устройстве смотрите?

Попробуйте код из комментария 3
Золочев Ларк
Можете посмотреть: zolochev.lark.ru
Google Hrom android.
Честно сломал мозг.
Ссылку вверху все нормально, которую Вы дали. Ставлю на сайт черт что.
NMitra
У меня Аваст ругается, а Мозила вообще отказался сайт загрузить, пишет, что соединение сброшено
Золочев Ларк
3 комментарий никакой разницы.
Золочев Ларк
Что это значит?
NMitra
Что я не могу загрузить ваш сайт, что возможно на сайте есть вирус
Золочев Ларк
Как проверить или чем?
Золочев Ларк
А если так: http://zolochev.lark.ru/strany/strany.html
Золочев Ларк
Там нет вашего скрипта
Золочев Ларк
Интересные у Вас система комментариев на сайте. Что это?
NMitra
Попробуйте https://yandex.ru/promo/manul#about (в видео рассказано как пользоваться https://events.yandex.ru/events/yamasterskaya/21-05-2015/ )
Блокируются не страницы, а домен
Это стандартная система комментариев Blogger. Впрочем, капчу можно установить на любой сайт http://www.google.com/recaptcha/intro/index.html
Золочев Ларк
Других вариантов нет для мобильного сайта выподающее горизонтальное, простое меню?
Золочев Ларк
Простое, чтобы не нагружать сайт, он у меня для слабых телефонов и опера мини заточен.
Более трех скриптов на сайте сильно тормозят загрузку сайта в опере мини, с телефона ( не Вайфай)
NMitra
Это самый простой вариант сделать меню выпадающим. Попробуйте посмотреть реализацию других авторов.
NMitra
Посмотрите исходный код http://www.cssplay.co.uk/menus/cssplay-responsive-multi-level-menu-jquery.html
Золочев Ларк
Наташа, спасибо за поддержку!
Золочев Ларк
В общем проблема в скрипте. Браузер: Яндекс, Гугл Хром - клик мимо меню- меню не сворачивается;
прокрутка вверх/вниз - Меню сворачивается, из-за чего невозможно нажать/увидеть пункты меню в самом внизу.
Проверял другие скрипты-все окей!
Тест был на сенсором экране.

Код который Вы мне дали- в закрытом состоянии под меню пустое место , размера меню когда оно открыто. Не очень красиво когда пол экрана пустое место.

Желаю Вам больше учиться и меньше писать и у других будет меньше проблем.

Не поленился выяснить: правда угрохал уйму времени , зря.
Удачи, Виктор Цой.
Золочев Ларк
Теперь ясно почему фавикон- дуля.
NMitra
Вы правы, не всегда получается ответственно подойти к вопросам, озвученным в комментариях http://shpargalkablog.ru/p/comments-blog.html Учту на будущее, что код нужно будет доработать, что есть проблемы с прокруткой на некоторых сенсорных устройствах. Сейчас, увы, нет возможности глубже рассмотреть проблему.

Извините за доставленное неудобство!
Анонимный
А как заменить надписи "меню" и "свернуть меню" на иконку-гамбугер?
Это в принципе возможно в данном коде?
NMitra
Вместо

content: "свернуть меню";
content: "меню";

напишите

content: url(http://f.cl.ly/items/1U2c3b1215383h3a2T2r/icon-menu.svg);

(картинку лучше поставить свою)
wakh
Приветствую, благодарю за сайт, нашёл пару удачных подсказок.
Если не трудно не могли бы вы помочь с ЦСС, вот тема на тостере:
https://toster.ru/q/282521
NMitra
Здравствуйте, ничего там не поделаешь, лучше использовать простенький JS, пока не будет всеобщей поддержки браузерами