Кроссбраузерный «аккордеон» с помощью CSS3
В последнее время, в силу того, что практически все современные и популярные браузеры (Opera, Firefox, Safari, Chrome, Flock и даже вечный тормоз — IE), активно подключаются к поддержке новых свойств CSS3, стало возможным в плотную заняться разработкой, более-менее кроссбраузерного, компактного «аккордеона», раскрывающегося при наведении. Конечно, способов создания таких «гармошек», в интернетах можно найти на любой вкус и цвет, все они разные и по исполнению, и по функциональной направленности.
Меня больше всего интересовала возможность создания панелей (меню) в стиле «аккордеон» исключительно средствами CSS3, без использования изображений при формировании блоков и без подключения дополнительных 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 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} |
/* Формируем блок аккордеона */ .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/
Здравствуйте!
Пересмотрел множество вариантов в интернете, прежде чем найти ваш и он оказался самым лучшим. Всё просто, доступно, без скриптов и сам принцип работы этого аккордеона считаю наиболее удобным.
Большое Вам спасибо!
Олег
Рад, что вам понравилась моя работа)))
А как переписать CSS что бы меню было не вертикальное а горизонтальное ?
Если это типа прикол, то совсем даже не смешно, а скорее наоборот. Если вам нужны шаблоны css для горизонтального меню, пройдитесь по записям, найдете как раз то что вам нужно.
Здравствуйте.
Прикрутил.
Работает во всех браузерах, кроме IE (9,10 — ниже не проверял). Конкретно — не работает псевдокласс :hover.
Не видит его вообще IE… 🙂
Возможно, нужен «костыль» какой-нибудь для него?
В чем может быть подковырка?
Co2FE. Доброго времени суток!
:hover как раз то и работает, только не все функции поддерживаются IEшкой, а именно свойство плавного перехода transition раскрытия блока с содержанием при наведении.
Если бы, как вы пишете IE не видел :hover вообще, то пункты меню ни как бы не реагировали при наведении и вы бы не увидели содержания скрытых блоков.
Так что «Аккордеон» работает во всех браузерах без исключения отлично. Повторюсь, в IEшке отсутствует лишь плавность раскрытия аккордеона и смещение ссылки при наведении происходит немного резче. Ну, на то он IE, чтоб нам работа медом не казалась.
Костыли для более старых версий IE 5.5 — IE 7 и IE 8, все же пришлось применить, в частности при создании эффекта линейного градиента.
Свойство transition на данный момент IE не поддерживается, а значит обойдемся пока в этом браузере без плавных переходов ))).
Работает…Проверил отдельно от CMS.
Отдельно, не в его структуре — все ОК!
А в CMS — не работает…Т.е. — работает во всех браузерах, кроме IE, где :hover вообще не реагирует и не открывает содержания скрытых блоков.
Ну да ладно… Это частный случай, видимо… Буду ковырять… 🙂
Co2FE
Спасибо за очень полезное дополнение.
Огромное спасибо за урок. Но насколько я понимаю, возможности оставлять одну из вкладок открытой здесь не предусмотрено? Все только по наведению курсора. Очень жаль. Хороший скрипт, особенно радует, что кроссбраузерный, но лично мне нужно было заполнить одну из пустовавших областей сайта несколько большим объемом контента.
Спасибо Автору очень понравилось.Вопрос:при наведении курсора
блок body еле заметно дергается влево.Как сделать что-бы подменю после открывания фиксировалось и не закрывалось при убирании курсора? Спасибо
Спасибо за отзыв.
Убрал
*{margin: 0;padding: 0;}
в стилях демо, сейчас все нормально должно быть. Бывает в ходе разработки забываешь подчищать код))). Фиксация выезжающих блоков в данном виде аккордеона не предусматривалась изначально. В другом способе разворачивания (при клике), блоки «аккордеона» будут фиксироваться и закрываться по стандарту, т.е. при повторном клике по заголовкам пунктов.Удачи!
меню просто супер…, сейчас в него картинки вместо текста вставляю — всё работает. Огромное спасибо, driver!!!!
Спасибо за отзыв. Рад, что вам пригодилось.
А как сделать чтобы первый пункт (Новости) по умолчанию был открыт
Для начала, добрый вечер, Тимур.
Самый простой способ, это создать отдельный класс для пункта, который вы хотите видеть открытым, в вашем случае это первый пункт, ну и обзовем класс, например
.first
. В CSS пропишим этот класс со следующими параметрамиdisplay:block;height: 300px;
. Высоту можете выставить свою. Необходимо чтобы это правило работало внутри основного блока.accordion
, значит на выхлопе получаем примерно следующее:.accordion .first{display:block;height: 300px;}
В завершение, уже в html, первому пункту меню присваиваем класс
first
, непосредственно в коде это будет выглядеть так:<li class="first">
, соответственно остальные пункты оставляете как есть. Если понадобится сделать открытым любой другой пункт, просто прописываете к немуclass="first"
.Удачи!
Нашел то, что искал «НАКОНЕЦ ТО»! Огромное человеческое спасибо. Сейчас буду сидеть разбирать его.
Огромадное СПС автору (ам) скрипта!
Здравствуйте, driver!
Подскажите пожалуйста:
1. Как сделать в этом меню «Аккордеон» открытие вкладок по клику?
2. Как сделать часть пунктов просто кнопками без выплывающего списка?
Спасибо Вам, меню очень понравилось!
Здравствуйте, Владимир.
В данном примере «аккордеон» выстроен в виде неупорядоченного списка, с раскрытием блоков с содержанием при наведении с помощью псевдокласса
:hover
, для активации скрытых боков по клику необходимо использовать другой псевдокласс:target
, но применительно к этой конструкции аккордеона, в таком виде как сейчас, он не сработает, нужно полностью перестраивать и html и часть css. В комментариях точно не уложимся)))В ближайшие два — три дня, заканчиваю развернутый материал, именно по теме «аккордеона» с активацией блоков через псевдокласс
:target
, а так же готов пример аккордеона на чекбоксах. Так что следите за обновлениями моего блога…Спасибо за ответ, по возможности обязательно буду следить за обновлениями Вашего блога. Благодарю Вас за то, что делитесь своим творчеством. Желаю Вам успехов и благополучия!
Отличный кроссбраузерный «аккордеон», пересмотрел множество вариантов, Ваш оказался наиболее удобным, отдельное спасибо за градиент для «Ослика»!
Добрый день! Статья супер, применил стили к стандартному меню джумла у себя на сайте.
Можно задать только один вопрос?
Хотелось бы прописать один из css3 стилей, что бы меню всегда открывалось до конца, не зависимо от времени наведения на него. Например сейчас, если навести мышь на меню и быстро убрать, то оно до конца не откроется, а сразу начнет сворачиваться. Это не очень удобно если высота всех подпунктов меню разная, а не как у вас в демо. (см. пример на моем сайте)
Можно ли что то прописать с помощью CSS3 или jqury для лечения этой проблемы? …то же самое относится и к движеню h3 с помощью padding-left, хотелось бы что бы движение всегда заканчивалось.
Здравствуйте, Владимир.
Такая функция мною не рассматривается, просто не вижу логики, если чел навел на пункт, он обязательно дождётся того, чтобы увидеть все скрытые пункты, а кому не интересно, нет разницы раскроется меню полностью после его судорожных наводок на пункты или нет)))
Могу показать на примере, почему меня эта функция заинтересовала )
сайт: favorkrep.ru
На меню «уплотнители» тяжело попасть, если вести сверху вниз курсор, т.к. случайно попадаешь на 3е меню (из-за закрывания 1го).
В общем, просто попробуйте, может есть еще какое решение…
Отлично! Как сделать чтобы при переходе по якорю вкладка октрывалась? так и не допетрил…
Здравствуйте. Спасибо вам большое за это меню, нашёл то что искал. Но существует проблема связанная с высотой секции, по умолчанию стоит 280px для всех, а мне необходимо для каждой свой размер. Понимаю, что параметры высоты для каждой секции можно задать отдельно в том же css, но как это сделать я не знаю, поскольку абсолютный «чайник» в «этих» делах.
Помогите пожалуйста)))
Если не критично отсутствие плавного перехода при раскрытии,достаточно изменить значение height с 300px на auto:
.accordion>ul>li:hover {
height: auto;
}
.accordion>ul>li:hover {
height: auto;
}
В этом случае блоки, будут атоматом подстраиваться под размер содержания.
Отличный сайт и урок. Большое спасибо! В том числе за мобильную версию сайта.
Вам спасибо за отзыв, приходите ещё)))
Андрею низкий поклон с Дальнего Востока и Юго Восточной Азии за крутой сайт и за аккордеон в частности!
Добрый вечер!
Не смог найти на Вашем сайте вариант этого аккордеона где бы он открывался бы по клику (target) а не по наведению (hover).
Заранее благодарен.
Есть парочка вариантов на скрытых чекбоксах: раз и два
Спасибо, что так быстро ответили. Предложенные вами варианты хорошие. Однако вешеизложенный Вами вариант кода аккордеона интересен тем, что имеет плавность при открытии или закрытии на одном только CSS и HTML (без использования JavaScript). Ещё круче было бы реализовать возможность открытия/закрытия при щелчке мыши (типа oclick но без JavaScript).
Эффекта плавности можно достичь, если слегка поменять принцип работы аккордеона. В примере, который я скинул в этом нам помогает max-height: 0 в закрытом состоянии и max-height: 200px в открытом, соответственно. Это позволяет браузеру во время рендеринга высоты блока просчитывать время, за которое этот блок откроется. Легкое притормаживание всё же будет, но плавность будет достигнута.
И сам пример: jsfiddle.net/wutnha1s/
Добрый день, а как сделать так, чтобы пункты аккордеона открывались в право, а не вниз?