Dobrovoi Master
сделано с душой
В состоянии постоянного подключения...

Как сделать простое адаптивное меню с помощью CSS3

Как сделать простое адаптивное меню с помощью CSS3

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

Читайте также: Чистый стиль меню с помощью CSS3

Предлагаю на рассмотрение, технику создания простого, очень гибкого в настройках, и к тому же достаточно эффективного, адаптивного меню, с использованием чистой семантической разметки, для реализации адаптивной конструкции, без подключения javascript. В результате с помощью CSS мы получим меню, которое может быть выравнено влево, вправо или располагаться точно по центру, выделяемые активные/текущие пункты, меню способное при изменении размера окна браузера, быстро перестраиваться в раскрывающуюся, вертикальную навигационную панель, которая замечательно смотрится на экранах различных мобильных пользовательских устройств(планшеты, смартфоны, ноутбуки и мобильные телефоны).
 
Простое адаптивное меню

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

HTML Разметка

Перво-наперво нам необходимо выполнить разметку всей основной конструкции нашего меню. Мы создаем элемент навигации, а значит логичным и даже практичным, будет применение HTML5-элемента, тега <nav> с присвоенным ему одноименным классом, для последующего форматирования CSS стилей, а также создания и абсолютного позиционирования выпадающей навигационной панели. Класс current указывает на активную / текущую ссылку меню, внешний вид которой, сформируем с помощью css.
 

<nav class="nav">
        <ul>
            <li class="current"><a href="#">Главная</a></li>
            <li><a href="#">О Нас</a></li>
            <li><a href="#">Портфолио</a></li>
            <li><a href="#">Наши Услуги</a></li>
            <li><a href="#">Контакты</a></li>
        </ul>
</nav>

 
Как видим, меню, это простой неупорядоченный список с определенным количеством ссылок. Количество пунктов может быть разным, но всё же не стоит городить огород, всё в разумных пределах.
Далее, пока не ушли далеко, хочу напомнить, а тем кто не знает, пояснить, что HTML5 и запросы media query не поддерживается IE версии старше 9-й(совсем неудивительно). Дабы избежать головной боли в будущем и сделать всё правильно, существуют специальные скрипты html5shiv и css3-mediaqueries-js, с помощью которого, мы сможем решить задачу совместимости, предусмотрительно подключив их к документу в разделе <head></head>.
 

<!--[if lt IE 9]>
        <script src="https://css3-mediaqueries-js.googlecode.com/files/css3-mediaqueries.js"></script>
        <script src="https://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->

 
Всё. С основной разметкой мы разобрались, классы прописаны, костыли добавлены. Теперь перейдем к определению стилей пунктов меню, сформируем внешний вид и с делаем наше меню по-настоящему адаптивным.
 

CSS Определяем стили

Набор стилей CSS меню под экраны мониторов настольных компьютеров, довольно стандартный, вдаваться в подробности не вижу смысла. Хочу лишь обратить внимание, на то что я указал display:inline-block вместо float:left элемента <li> в контейнере навигации nav. Это позволит выравнивать пункты меню влево, вправо и точно по центру, указав свойство text-align элементу списка <ul>.
 

/* меню */
.nav {
        margin: 20px 0;
}
.nav ul {
        margin: 0;
        padding: 0;
}
.nav li {
        margin: 0 5px 10px 0;
        padding: 0;
        list-style: none;
        display: inline-block;
        *display:inline; /* ie7 */
}
.nav a {
        padding: 3px 12px;
        text-decoration: none;
        color: #999;
        line-height: 100%;
}
.nav a:hover {
        color: #000;
}
.nav .current a {
        background: #999;
        color: #fff;
        border-radius: 3px;
}

За изменения цвета ссылок и фона активных/текущих пунктов меню отвечают секции .nav a:hover и .nav .current a соответственно. Я не стал особо мудрить в этом примере, всё сделал в духе минимализма, при наведении на ссылку меняется цвет, текст становится черным color: #000;, а для активных пунктов добавил фон background: #999;, заменил цвет шрифта на белый color: #fff; и чуточку закруглил края border-radius: 3px; у получившейся кнопки. Вы же можете фантазировать и экспериментировать в этом плане, сколь душе угодно.
 

Выравнивание по центру и вправо

Как я уже упоминал выше, мы можем изменять выравнивание пунктов навигации с помощью свойства text-align, для этого добавим в код CSS несколько строк:
 

/* меню справа */
.nav.right ul {
        text-align: right;
}
 
/* меню по центру */
.nav.center ul {
        text-align: center;
}

 

Адаптируем меню

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

Будем исправлять ситуацию с помощью медиа запросов. В точке приложения медиа запроса в 600px, выставил относительное позиционирование position: relative; для элемента nav, чтобы мы смогли потом разместить список меню <ul> сверху в абсолютной позиции position: absolute;. С помощью свойства display: none скроем все пункты меню li, оставив только активные на текущий момент ссылки с классом current, прописав им свойство display: block
При наведении на сгруппированную панель навигации все пункты меню должны показываться в виде выпадающего списка, для этого определяем правило .nav ul:hover li с функцией code>display: block. Для активных/текущих пунктов добавляем иконку, чтобы выделить из из остальных.
Если необходимо сместить меню вправо или расположить по центру, воспользуйтесь left и right свойствами позиционирования для списка ul нашего меню.
 

@media screen and (max-width: 600px) {
        .nav {
                position: relative;
                min-height: 40px;
        }     
        .nav ul {
                width: 180px;
                padding: 5px 0;
                position: absolute;
                top: 0;
                left: 0;
                border: solid 1px #aaa;
                background: #FAFAFA url(images/icon-menu.png) no-repeat 10px 11px;
                border-radius: 5px;
                box-shadow: 0 1px 2px rgba(0,0,0,.3);
        }
        .nav li {
                display: none; /* скрыть все <li> пункты */
                margin: 0;
        }
        .nav .current {
                display: block; /* показывать только текущие активные <li> пункты */
        }
        .nav a {
                display: block;
                padding: 5px 5px 5px 32px;
                text-align: left;
        }
        .nav .current a {
                background: none;
                color: #666;
        }
 
        /* при наведении на пункты меню */
        .nav ul:hover {
                background-image: none;
        }
        .nav ul:hover li {
                display: block;
                margin: 0 0 5px;
        }
        .nav ul:hover .current {
                background: url(/wp-content/uploads/images/icon-check.png) no-repeat 10px 7px;
        }
 
        /* адаптивное меню справа */
        .nav.right ul {
                left: auto;
                right: 0;
        }
 
        /* адаптивное меню по центру */
        .nav.center ul {
                left: 50%;
                margin-left: -90px;
        }
 
}

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

Урок подготовлен по материалам Web designer wall
Вольный перевод и адаптация: Андрей /driver/
 
Удачи!
Буду очень признателен, если поделитесь ссылкой на этот урок в своих соц-сетях:

Всего комментариев: 41

  • Nina: 29 апреля, 2014 в 17:51

    Вы на телефоне пробовали таким меню попользоваться?

    Ответить
    • driver: 29 апреля, 2014 в 22:51

      А ВЫ? В чём вопрос то? Пробовал конечно, всё сначала тестирую, и…

      Ответить
  • Георгий: 15 июня, 2014 в 16:36

    присоединяюсь!!!Вы на телефоне пробовали таким меню попользоваться?
    дело в том что когда кликаешь на телефоне то выбирается сразу активный пункт, смысл в том что меню должно раскрыться по клику а не в момент когда под тапом или мышью!!!

    Ответить
    • driver: 15 июня, 2014 в 22:58

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

      Ответить
      • Вячеслав: 27 декабря, 2014 в 09:17

        На сенсоре нету такой функции как наведение, происходит сразу клик. И при попытки раскрыть меню с телефона срабатывает адресация на ссылку. Попробуйте например onclick (alert (‘+’)); или реальные ссылки добавить и поймете в чем косяк Вашего примера

        Ответить
  • Алексей: 19 июня, 2014 в 17:51

    Очень глупый вопрос, как сделать мобильную версию меню по центру, туплю.

    Ответить
    • driver: 19 июня, 2014 в 23:51

      Бывает))) Смотрите в статье раздел «Выравнивание по центру и вправо», всё предельно ясно расписано и приведены примеры кода CSS

      Ответить
  • Artur: 20 июня, 2014 в 11:53

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

    Ответить
    • NeedHate: 23 июня, 2014 в 22:58

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

      Ответить
  • Иван: 5 сентября, 2014 в 13:30

    Столкнулся с той же проблемой. Видимо ее придется решать подставляя в адрес current #

    Ответить
  • Антон: 1 марта, 2015 в 00:50

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

    Ответить
  • NeedHate: 1 марта, 2015 в 12:37

    Даже я не сдержусь. А в чем проблема? Всё работает при клике. Меню открывается. Список выпадает. Никуда ничто не пропадает. Если нужно эмитировать :hover эффект, то просто напросто добавляем aria-haspopup=”true” в тег, на котором срабатывает :hover. Всё!

    Ответить
  • Иван Половников: 3 июля, 2015 в 17:52

    А то что в сенсорных телефонах нет состояния наведения (hover), там же касания, а не курсор мышки. И потому данное меню трудно назвать адаптивным под все устройства. Оно просто сворачивается и занимает меньшее пространство.
    А так спс, за пост!

    Ответить
    • driver: 9 июля, 2015 в 06:19

      Идея подана, а там хоть лом прикрутите)))

      Ответить
  • bairon: 13 октября, 2015 в 23:55

    stihok.ru опубликовать произведения, ну и т.д.
    Делал мобильную версию, по дизайну меню подошло. Правильно писали выше — при нажатии срабатывает сразу первая ссылка. Я просто убрал ссылку и написал «МЕНЮ» )), так как попасть пальцем в маленький полосатый квадратик было сложно. Всё нормально работает, есть правда один нюанс — в содержании есть то же пункты меню, вот они вылазят по верх этого меню. Вопрос — как это исправить? Заранее спасибо!

    Ответить
  • Вася: 15 октября, 2015 в 14:48

    Ну вот у меня на galaxy S4 (на новых моделях скорее тоже) есть функция срабатывания при наведение… hover отлично отрабатывает, но особого смысла на самом деле я в этом не вижу. Для меня куда более удобно когда меню открывается при тапе (на мобильных девайсах естественно)

    Ответить
  • kolver: 12 марта, 2016 в 20:56

    Уважаемые,подскажите; куда вставляется картинка noise.png из архива?

    Ответить
    • driver: 12 марта, 2016 в 22:27

      Здравствуйте.
      noise.png это background (фон) демо-страницы, как вы понимаете фон у вас может быть абсолютно другим, а располагается картинка в папке images,
      Свойство в селекторе body:
      background: #efefef url(images/noise.png) repeat 0 0;
      Соответственно, если вы закинете картинки в папку с другим именем, то и путь до файлов в CSS, не забудьте указать правильно.

      Ответить
      • kolver: 12 марта, 2016 в 22:30

        driver, большое спасибо за разъяснение. Я только еще учусь ))

        Ответить
  • Андрей: 17 мая, 2016 в 14:14

    у меня при проверке на мобильных десктопах вместо меню расположена просто узкая серая линия (это граница: border: solid 1px #aaa;) Если коснуться этой границы где-то задевается меню и оно выскакивает.

    Ответить
  • Андрей: 17 мая, 2016 в 14:16

    А еще…когда нажимаешь на пункт адаптивного меню и переходишь на соответствующую страницу, там меню показывается уже не адаптивное.

    Ответить
  • Наталья: 29 ноября, 2016 в 00:49

    А у меня обнаружилась такая проблема. В готовом варианте при постепенном уменьшении размера окна браузера пункты меню смещаются также, как описано в подразделе «Адаптируем меню». И только при минимальном размере окошка вместо сместившихся пунктов меню пропадают все, кроме первого пункта.
    У Вас на демо такого нет.
    Не понимаю, что сделала неправильно. Вроде бы все повторила в точности.

    Ответить
  • Наталья: 29 ноября, 2016 в 01:16

    И еще раз проверила. Просмотрела исходный код страницы «Демо».
    Скопировала оттуда соответствующий код + открыла указанный там файл со стилями.
    Скопировала в редактор, открыла в браузере — все работает. Значит, ошибка где-то в коде, который приведен в статье.
    Автор, проверьте, будьте добры. Это отличное меню. Было бы прекрасно, если бы заработало сразу. Не пришлось бы заглядывать к Вам в код. (за это уж извините — очень было нужно, чтобы заработало).
    А так, статья очень мне пригодилась. Даже я — совершенный новичок в CSS, а все ж таки в итоге получила то, что хотела.
    Спасибо! И проверьте, все-таки, код, приведенный в примере.

    Ответить
    • driver: 29 ноября, 2016 в 01:57

      Здравствуйте, Наталья.
      Спасибо за интерес к статье и внимание. При минимальном размере меню рядом с «гамбургер» иконкой отображается заданный пункт меню. В первом случае это пункт «Главная», во втором пункт «О Нас», для активных пунктов в html прописывается определённый класс .curren Вот такая задумка, если вы хjтите чтобы при минимальном размере отображадась только иконка «гамбургер», в ближайшее время проработаю и такой вариант

      Ответить
      • Наталья: 29 ноября, 2016 в 02:30

        Нет, спасибо. Меня все очень устраивает в таком виде, как сейчас. Я хотела только обратить Ваше внимание на то, что при постепенном уменьшении размера окна страницы(код которой написан в соответствии с приведенным Вами в уроке) все пункты меню смещаются и отображаются «как им вздумается».
        Попробуйте сами этот код внести в редактор (у меня Dreaweaver) и открыть просмотр в браузере. (Именно код, который Вы привели в примере. Он, видимо, немножко отличается от того, который Вы использовали для создания «Демо») И уменьшайте окно постепенно.
        В варианте из статьи: на определенном этапе уменьшения размера окна браузера получается смещение пунктов меню. Не исчезновение их, как в варианте «Демо», а сначала они сдвигаются беспорядочно, и только потом пропадают при дальнейшем уменьшении. Это, я думаю, не есть хорошо, т.к. никто не знает, какого размера окно браузера у посетителя сайта. Может, он не разворачивает окна максимально, или новое окно у него настроено открываться не полноразмерным.
        А при использовании кусочка кода Вашей страницы «Демо» такого перехода нет. Все пункты меню, кроме активного сразу пропадают при значительном уменьшении окна. И остается только пункт «Главная», как и должно быть. Без этого несимметричного смещения.
        Я не проводила сверки одного кода и другого. Мне, как новичку, придется по символам сверять, я не очень хорошо понимаю, что именно и где указано. А Вы, наверняка, быстрее меня увидите различия.
        Где-то там есть это расхождение. Раз из примера не работало корректно, а из демо — заработало отлично.
        В любом случае, большое Вам спасибо! 🙂

        Ответить
  • skif88: 30 декабря, 2016 в 20:28

    О, ништяк. Сейчас ништяки на css мне нравятся. Не надо js лишний раз использовать. html+css классика)
    Хорошо сделано, переделал под дизайн сайта и моб.версия стала проще. Разработчику огромное спасибо.

    Ответить
  • Руслан: 4 февраля, 2017 в 08:16

    Привет, а как полностью скрыть основное меню для мобильных устройтв? Чтоб ни ссылок ни кнопки с навигационным полем не показывать?

    Ответить
    • Роман: 29 июля, 2017 в 00:45

      а в зависимости от @media display, не?

      Ответить
  • Dimon: 20 августа, 2017 в 20:37

    Спасибо за статью, очень интересная. Смущает одно … У Вас ус отклеился… указали класс для хранения состояния выбранного элемента — а как вы потом тыкая по элементу будете этот класс перекидывать на другой элемент без js кода?

    Ответить
    • driver: 20 августа, 2017 в 21:35

      Здравствуйте, Dimon.
      Дык дело то всё в том, что в данной статье элементарно расписан ещё один вариант (из многих) css-вёрстки менюшки под мобильные устройства и всего лишь, дальше вы можете прикрутить всё что угодно (jQuery Cookie например).

      Ответить
      • Dimon: 22 августа, 2017 в 14:35

        Это да. А галочку поставить на выбранной ссылке можно и через css (через :target — меньше js кода), хотя это наверно уже вопрос предпочтений.
        P.S. оставил этот коммент на случай если кто искать будет (я убил на это целый день)

        Ответить
  • Дмитрий: 30 октября, 2017 в 13:37

    Добый ень,отличное меню. Скажите а как можно вместо иконки в мобильной версии вывести текст, меню?

    Ответить
  • driver: 30 октября, 2017 в 18:03

    Здравствуйте Дмитрий.
    По умолчанию, в мобильной версии показывается иконка и текст ” ☰ Главная “, для того чтобы оставить только текст, в медиа-запросе @media screen and (max-width: 600px), в селекторах .nav ul и .nav ul:hover .current исключите или закомментируйте свойство background: или просто измените значение на background: none;, всё, у вас будет выводится только текст

    Ответить
    • Дмитрий: 1 ноября, 2017 в 16:49

      Спасибо разобрался! У меня изначально иконка тоже не выводилась … Оказывается она привязана к классу

      Ответить
  • Миха: 24 ноября, 2017 в 14:36

    Полезная статья. Спасибо!

    Ответить
  • Dexter: 26 июля, 2018 в 18:08

    Минус есть существенный — выпадающее меню не убирается по клику.

    Ответить
  • Alex: 9 сентября, 2018 в 23:50

    Добрый день! Проблема с картинкой. Если быть точнее, она не отображается. С чем это может быть связано?

    Ответить
  • kinogrant: 12 ноября, 2018 в 05:08

    Спасибо большое, отличная статья, помогли!

    Ответить
  • софия: 27 ноября, 2019 в 22:08

    подскажите как увеличить пункты меню в изначальном варианте

    Ответить

Оставить комментарий

Ваш email не будет опубликован.

Вы можете использовать следующие HTML тэги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>