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

Кроссбраузерный «аккордеон» с помощью CSS3

Кроссбраузерный «аккордеон» с помощью CSS3

В последнее время, в силу того, что практически все современные и популярные браузеры (Opera, Firefox, Safari, Chrome, Flock и даже вечный тормоз — IE), активно подключаются к поддержке новых свойств 3, стало возможным в плотную заняться разработкой, более-менее кроссбраузерного, компактного «аккордеона», раскрывающегося при наведении. Конечно, способов создания таких «гармошек», в интернетах можно найти на любой вкус и цвет, все они разные и по исполнению, и по функциональной направленности.
Меня больше всего интересовала возможность создания панелей () в стиле «» исключительно средствами , без использования изображений при формировании блоков и без подключения дополнительных javascript. Ну и конечно же самое главное, чтоб в итоге, получился полноценный рабочий элемент, одинаково хорошо работающий во всех браузерах.

Сегодня, мы вместе с вами, рассмотрим всю технику исполнения кроссбраузерного «аккордеона» на чистом CSS3. Без лишней воды, нагромождений кода, только практика и наглядный пример. Кстати, а вот и он:

За основу построения структуры меню, были взяты ранние наработки по теме, описанные в статье: Меню «Аккордеон» без javascript и изображений.
В обновленной версии, мы будем использовать, при формировании внешнего вида аккордеона, функцию линейного градиента, эффекты трансформации открывающихся блоков и активных пунктов меню. В дальнейшем при желании, сможете с помощью магии CSS3, добавить чуточку размытой тени, экспериментируя со свойством box-shadow.
 

Меню в стиле Аккордеон

 
Примеры посмотрели, надеюсь разница работы старой и новой версий меню стала очевидной, особенно если не забыли просмотреть и в IEшке. Теперь, давайте подробнее рассмотрим полный расклад всех составляющих нашего «аккордеона», базовый html-каркас, и стили CSS, с помощью которых, сформируем внешний вид и функциональность панелей.

Разметка HTML

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

<div class="accordion">
    <ul>
        <li>
            <h3>»  Заголовок №1</h3>
            <div>
               <p>
                  Здесь любое содержание....
               </p>
            </div>
        </li>
        <li>
            <h3>»  Заголовок №2</h3>
            <div>
               <p>
                  Здесь любое содержание....
               </p>
            </div>
        </li>
        <li>
            <h3>»  Заголовок №3</h3>
            <div>
               <p>
                  Здесь любое содержание....
               </p>
            </div>
        </li>
        <li>
            <h3>»  Заголовок №4</h3>
            <div>
               <p>
                  Здесь любое содержание....
               </p>
            </div>
        </li>
    </ul>
</div>

 
Как видите, каркас меню не содержит ничего лишнего, вам остается только, при необходимости, по своему редактировать пункты(добавлять или удалять) и наполнять содержанием встроенные блоки div. Для связки нашего «аккордеона» с CSS, основному div-контейнеру, мы прописали определенный класс: class="accordion". С эти классом нам и предстоит работать в .css, дабы сформировать внешний вид, и оживить раскрывающиеся блоки, без использования javascript.

CSS3

Для оформления пунктов аккордеона, используем функцию линейного градиента linear-gradient и эффект тени для текста text-shadow в заголовках. Ну, а чтобы немного придать движухи при наведении и раскрытии панелей с содержанием, используем свойство из обоймы CSS3 transition. Это же свойство в связке с padding-left: 30px, применяем к заголовкам основных пунктов, добиваясь эффекта скольжения при наведении.
Как вы понимаете, значения необязательные и вам никто не мешает экспериментировать. Некоторые пояснения, непосредственно в коде CSS, помогут вам разобраться.
 

/* Формируем блок аккордеона */
.accordion {
    width: 100%;
    max-width: 300px;
    margin: 0 auto;
    border: 1px solid #d3d3d3;
    border-radius: 3px;
    overflow: hidden;
}
/* список аккордеона */
.accordion>ul {
    margin: 0;
    padding: 0;
    list-style:none;
}
.accordion>ul>li {
    display:block;
    overflow: hidden;
    margin: 0;
    padding: 0;
    height:36px;
    max-width: 300px;
/* задержка перехода при раскрытии */
    transition: height 0.5s ease-in-out;
    -moz-transition: height 0.5s ease-in-out;
    -webkit-transition: height 0.5s ease-in-out;
    -o-transition: height 0.5s ease-in-out;
}
/* оформляем пункты */
.accordion>ul>li>h3 {
    display:block;
    margin: 0 auto;
    padding:10px 20px;  
    color: #6c6c6c;
    text-decoration: none;
    font: 14px  Helvetica, Arial, Sans-Serif;
    text-shadow: 1px 1px #fff;
    text-transform:uppercase;
    background: #c9c9c9;
    border-top: 1px solid #f4f4f4;
    border-bottom: 1px solid #d3d3d3;
/* градиент */
    -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr = '#f0f0f0', endColorstr = '#c9c9c9')";
    background-image: -moz-linear-gradient(top, #f0f0f0, #c9c9c9);
    background-image: -ms-linear-gradient(top, #f0f0f0, #c9c9c9);
    background-image: -o-linear-gradient(top, #f0f0f0, #c9c9c9);
    background-image: -webkit-gradient(linear, center top, center bottom, from(#f0f0f0), to(#c9c9c9));
    background-image: -webkit-linear-gradient(top, #f0f0f0, #c9c9c9);
    background-image: linear-gradient(top, #f0f0f0, #c9c9c9);
/* анимируем заголовок */
   -o-transition: padding-left 250ms ease-out;
   -webkit-transition: padding-left 250ms ease-out;
   -moz-transition: padding-left 250ms ease-out;
}
/* блок с содержанием */
.accordion>ul>li>div {
    background-color:#fcfcfc;
    margin: 0 auto;
    padding:10px;
    color: #555;
    font-size: 14px;
    height: 100%;
}
.accordion>ul>li:hover {
    height: 280px;
}
/* пункты аккордеона при наведении */
.accordion:hover>ul>li:hover>h3 {
    /* оформляем пункты при наведении */
    color: #3A505C;
    background: #d3d3d3;
    cursor:pointer;
    /* градиент */
    background-image: -moz-linear-gradient( top, #d3d3d3, #efefef);
    background-image: -ms-linear-gradient( top, #d3d3d3, #efefef);
    background-image: -webkit-gradient(linear, left top, left bottom, from(#d3d3d3), to(#efefef));
    background-image: -o-linear-gradient(#dbdbdb, #e6e6e6); /* Opera */
    filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr = '#d3d3d3', endColorstr='#efefef')"; /* IE 7 */
    -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr= '#d3d3d3', endColorstr= '#efefef')";   /* IE 8 */
/* подвижная ссылка */
   padding-left: 30px;
}
/* параграфы внутри аккордеона */
.accordion p { margin: 0 0 10px }
/* миниатюры изображений */
.accordion img{ width: 25%; height: auto}

 
Internet Explorer, этот вечный тормоз, не позволяющий веб-разработчикам расслабиться, на сей раз прожевал все, что ему предложили. Правда, для более старых версий(IE 5.5 — IE 7 и IE 8) , все же пришлось применить некоторые «костыли», в виде фильтров при создании эффекта линейного градиента в оформлении пунктов «аккордеона».

В итоге, если вы внимательно изучите данный урок и всё сделаете правильно, не боясь при этом экспериментировать, вы научитесь создавать замечательные блоки навигации в стиле «Аккордеон», без использования дополнительных файлов изображений и подключения javascript.
 

С уважением, Андрей Лазаренко /shurawi/

 

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

  • Олег: 2 февраля, 2013 в 13:45

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

    Ответить
    • driver: 2 февраля, 2013 в 15:23

      Олег
      Рад, что вам понравилась моя работа)))

      Ответить
  • romaamor: 8 февраля, 2013 в 03:50

    А как переписать CSS что бы меню было не вертикальное а горизонтальное ?

    Ответить
    • driver: 8 февраля, 2013 в 19:50

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

      Ответить
  • Co2FE: 12 февраля, 2013 в 17:48

    Здравствуйте.
    Прикрутил.
    Работает во всех браузерах, кроме IE (9,10 — ниже не проверял). Конкретно — не работает псевдокласс :hover.
    Не видит его вообще IE… 🙂
    Возможно, нужен «костыль» какой-нибудь для него?
    В чем может быть подковырка?

    Ответить
    • driver: 12 февраля, 2013 в 19:14

      Co2FE. Доброго времени суток!
      :hover как раз то и работает, только не все функции поддерживаются IEшкой, а именно свойство плавного перехода transition раскрытия блока с содержанием при наведении.
      Если бы, как вы пишете IE не видел :hover вообще, то пункты меню ни как бы не реагировали при наведении и вы бы не увидели содержания скрытых блоков.
      Так что «Аккордеон» работает во всех браузерах без исключения отлично. Повторюсь, в IEшке отсутствует лишь плавность раскрытия аккордеона и смещение ссылки при наведении происходит немного резче. Ну, на то он IE, чтоб нам работа медом не казалась.
      Костыли для более старых версий IE 5.5 — IE 7 и IE 8, все же пришлось применить, в частности при создании эффекта линейного градиента.
      Свойство transition на данный момент IE не поддерживается, а значит обойдемся пока в этом браузере без плавных переходов ))).

      Ответить
      • Co2FE: 12 февраля, 2013 в 19:42

        Работает…Проверил отдельно от CMS.
        Отдельно, не в его структуре — все ОК!
        А в CMS — не работает…Т.е. — работает во всех браузерах, кроме IE, где :hover вообще не реагирует и не открывает содержания скрытых блоков.
        Ну да ладно… Это частный случай, видимо… Буду ковырять… 🙂

        Ответить
  • driver: 12 февраля, 2013 в 22:48

    Co2FE
    Спасибо за очень полезное дополнение.

    Ответить
  • Ринат: 7 марта, 2013 в 08:40

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

    Ответить
  • Евгений: 1 апреля, 2013 в 14:29

    Спасибо Автору очень понравилось.Вопрос:при наведении курсора
    блок body еле заметно дергается влево.Как сделать что-бы подменю после открывания фиксировалось и не закрывалось при убирании курсора? Спасибо

    Ответить
    • driver: 1 апреля, 2013 в 21:49

      Спасибо за отзыв.
      Убрал *{margin: 0;padding: 0;} в стилях демо, сейчас все нормально должно быть. Бывает в ходе разработки забываешь подчищать код))). Фиксация выезжающих блоков в данном виде аккордеона не предусматривалась изначально. В другом способе разворачивания (при клике), блоки «аккордеона» будут фиксироваться и закрываться по стандарту, т.е. при повторном клике по заголовкам пунктов.
      Удачи!

      Ответить
  • vektorss: 24 апреля, 2013 в 15:19

    меню просто супер…, сейчас в него картинки вместо текста вставляю — всё работает. Огромное спасибо, driver!!!!

    Ответить
    • driver: 24 апреля, 2013 в 16:21

      Спасибо за отзыв. Рад, что вам пригодилось.

      Ответить
  • Тимур: 22 мая, 2013 в 19:30

    А как сделать чтобы первый пункт (Новости) по умолчанию был открыт

    Ответить
    • driver: 22 мая, 2013 в 22:49

      Для начала, добрый вечер, Тимур.
      Самый простой способ, это создать отдельный класс для пункта, который вы хотите видеть открытым, в вашем случае это первый пункт, ну и обзовем класс, например .first. В CSS пропишим этот класс со следующими параметрами display:block;height: 300px;. Высоту можете выставить свою. Необходимо чтобы это правило работало внутри основного блока .accordion, значит на выхлопе получаем примерно следующее: .accordion .first{display:block;height: 300px;}
      В завершение, уже в html, первому пункту меню присваиваем класс first, непосредственно в коде это будет выглядеть так: <li class="first">, соответственно остальные пункты оставляете как есть. Если понадобится сделать открытым любой другой пункт, просто прописываете к нему class="first".
      Удачи!

      Ответить
  • Vad: 3 сентября, 2013 в 20:26

    Нашел то, что искал «НАКОНЕЦ ТО»! Огромное человеческое спасибо. Сейчас буду сидеть разбирать его.

    Ответить
  • Alex: 8 ноября, 2013 в 22:13

    Огромадное СПС автору (ам) скрипта!

    Ответить
  • Владимир: 14 февраля, 2014 в 22:34

    Здравствуйте, driver!
    Подскажите пожалуйста:
    1. Как сделать в этом меню «Аккордеон» открытие вкладок по клику?
    2. Как сделать часть пунктов просто кнопками без выплывающего списка?
    Спасибо Вам, меню очень понравилось!

    Ответить
    • driver: 15 февраля, 2014 в 03:57

      Здравствуйте, Владимир.
      В данном примере «аккордеон» выстроен в виде неупорядоченного списка, с раскрытием блоков с содержанием при наведении с помощью псевдокласса :hover, для активации скрытых боков по клику необходимо использовать другой псевдокласс :target, но применительно к этой конструкции аккордеона, в таком виде как сейчас, он не сработает, нужно полностью перестраивать и html и часть css. В комментариях точно не уложимся)))
      В ближайшие два — три дня, заканчиваю развернутый материал, именно по теме «аккордеона» с активацией блоков через псевдокласс :target, а так же готов пример аккордеона на чекбоксах. Так что следите за обновлениями моего блога…

      Ответить
      • Владимир: 16 февраля, 2014 в 18:41

        Спасибо за ответ, по возможности обязательно буду следить за обновлениями Вашего блога. Благодарю Вас за то, что делитесь своим творчеством. Желаю Вам успехов и благополучия!

        Ответить
  • Олег: 27 марта, 2014 в 10:35

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

    Ответить
  • Владимир: 23 апреля, 2014 в 12:55

    Добрый день! Статья супер, применил стили к стандартному меню джумла у себя на сайте.
    Можно задать только один вопрос?
    Хотелось бы прописать один из css3 стилей, что бы меню всегда открывалось до конца, не зависимо от времени наведения на него. Например сейчас, если навести мышь на меню и быстро убрать, то оно до конца не откроется, а сразу начнет сворачиваться. Это не очень удобно если высота всех подпунктов меню разная, а не как у вас в демо. (см. пример на моем сайте)
    Можно ли что то прописать с помощью CSS3 или jqury для лечения этой проблемы? …то же самое относится и к движеню h3 с помощью padding-left, хотелось бы что бы движение всегда заканчивалось.

    Ответить
    • driver: 23 апреля, 2014 в 20:53

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

      Ответить
      • Владимир: 23 апреля, 2014 в 21:58

        Могу показать на примере, почему меня эта функция заинтересовала )
        сайт: favorkrep.ru
        На меню «уплотнители» тяжело попасть, если вести сверху вниз курсор, т.к. случайно попадаешь на 3е меню (из-за закрывания 1го).
        В общем, просто попробуйте, может есть еще какое решение…

        Ответить
  • Павел: 20 июля, 2014 в 14:31

    Отлично! Как сделать чтобы при переходе по якорю вкладка октрывалась? так и не допетрил…

    Ответить
  • Руслан: 5 сентября, 2014 в 13:37

    Здравствуйте. Спасибо вам большое за это меню, нашёл то что искал. Но существует проблема связанная с высотой секции, по умолчанию стоит 280px для всех, а мне необходимо для каждой свой размер. Понимаю, что параметры высоты для каждой секции можно задать отдельно в том же css, но как это сделать я не знаю, поскольку абсолютный «чайник» в «этих» делах.
    Помогите пожалуйста)))

    Ответить
    • driver: 5 сентября, 2014 в 21:55

      Если не критично отсутствие плавного перехода при раскрытии,достаточно изменить значение height с 300px на auto:

      .accordion>ul>li:hover {
      height: auto;
      }
      .accordion>ul>li:hover {
      height: auto;
      }

      В этом случае блоки, будут атоматом подстраиваться под размер содержания.

      Ответить
  • елена: 24 марта, 2015 в 22:04

    Отличный сайт и урок. Большое спасибо! В том числе за мобильную версию сайта.

    Ответить
    • driver: 25 марта, 2015 в 00:42

      Вам спасибо за отзыв, приходите ещё)))

      Ответить
  • Petr de Cril'on: 1 декабря, 2015 в 11:54

    Андрею низкий поклон с Дальнего Востока и Юго Восточной Азии за крутой сайт и за аккордеон в частности!

    Ответить
  • coder: 8 марта, 2016 в 00:54

    Добрый вечер!
    Не смог найти на Вашем сайте вариант этого аккордеона где бы он открывался бы по клику (target) а не по наведению (hover).
    Заранее благодарен.

    Ответить
    • driver: 8 марта, 2016 в 02:23

      Есть парочка вариантов на скрытых чекбоксах: раз и два

      Ответить
      • coder: 8 марта, 2016 в 05:35

        Спасибо, что так быстро ответили. Предложенные вами варианты хорошие. Однако вешеизложенный Вами вариант кода аккордеона интересен тем, что имеет плавность при открытии или закрытии на одном только CSS и HTML (без использования JavaScript). Ещё круче было бы реализовать возможность открытия/закрытия при щелчке мыши (типа oclick но без JavaScript).

        Ответить
  • NeedHate: 8 марта, 2016 в 13:47

    Эффекта плавности можно достичь, если слегка поменять принцип работы аккордеона. В примере, который я скинул в этом нам помогает max-height: 0 в закрытом состоянии и max-height: 200px в открытом, соответственно. Это позволяет браузеру во время рендеринга высоты блока просчитывать время, за которое этот блок откроется. Легкое притормаживание всё же будет, но плавность будет достигнута.
    И сам пример: jsfiddle.net/wutnha1s/

    Ответить
  • Мария: 7 октября, 2016 в 11:24

    Добрый день, а как сделать так, чтобы пункты аккордеона открывались в право, а не вниз?

    Ответить

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

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

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