Webmasters.BY

Главная Статьи Верстка сайтов Фильтрация контента при помощи CSS3
Фильтрация контента при помощи CSS3
Рейтинг пользователей: / 2
ХудшийЛучший 
10.01.2012 00:00

Фильтр контента при помощи CSS3

Используя псевдо-класс :checked, можно переключать состояния таких элементов, как checkbox или radio-кнопки. На этом уроке мы будем изучать это свойство CSS3, создав экспериментальный фильтр для портфолио, который будет переключать состояния элементов определенного типа.

На этот урок меня вдохновил блестящей эксперимент Романа Комарова "Фильтрация элементов без JS", в котором он использует флажки и переключатели для фильтрации цветных форм.

HTML-разметка

Давайте начнем с разметки. Наша цель создать четыре кнопки-фильтра, после нажатия на которые, соответствующие элементы портфолио будут появляются или исчезать. Итак, мы будем использовать несколько переключателей, все они имеют одинаковое имя, так как они должны принадлежать к одной группе (поэтому только один переключатель будет иметь состояние "checked" ). По умолчанию, мы хотим, чтобы все переключатели были выбраны или отмечены. Мы добавим несколько тегов label для радио-кнопок, которые мы будем использовать, чтобы скрыть переключатели. Нажатие на label выберет радио кнопку с соответствующими id:

<section class="ff-container">

 <input id="select-type-all" name="radio-set-1" type="radio" class="ff-selector-type-all" checked="checked" />
 <label for="select-type-all" class="ff-label-type-all">All</label>

 <input id="select-type-1" name="radio-set-1" type="radio" class="ff-selector-type-1" />
 <label for="select-type-1" class="ff-label-type-1">Web Design</label>

 <input id="select-type-2" name="radio-set-1" type="radio" class="ff-selector-type-2" />
 <label for="select-type-2" class="ff-label-type-2">Illustration</label>

 <input id="select-type-3" name="radio-set-1" type="radio" class="ff-selector-type-3" />
 <label for="select-type-3" class="ff-label-type-3">Icon Design</label>

 <div class="clr"></div>

 <ul class="ff-items">
 <li class="ff-item-type-1">
 <a href="">
 <span>Chameleon</span>
 <img src="images/1.jpg" />
 </a>
 </li>
 <li class="ff-item-type-2">
 <!-- ... -->
 </li>
 <li class="ff-item-type-3">
 <!-- ... -->
 </li>
 <!-- ... -->
 </ul>

</section>

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

CSS

Мы создадим три примера этого эффекта, но сначала давайте посмотрим на общие стили.

Я опускаю все префиксы браузеров, но вы можете найти их в исходниках.

Основной контейнер будет иметь фиксированную ширину:

.ff-container{
 width: 564px;
 margin: 10px auto 30px auto;
}

Теги label будут скрывать радио-кнопки и мы зададим им градиент и небольшие тонкие тени:

.ff-container label{
 font-family: 'BebasNeueRegular', 'Arial Narrow', Arial, sans-serif;
 width: 25%;
 height: 30px;
 cursor: pointer;
 color: #777;
 text-shadow: 1px 1px 1px rgba(255,255,255,0.8);
 line-height: 33px;
 font-size: 19px;
 background: linear-gradient(top, #ffffff 1%,#eaeaea 100%);
 float:left;
 box-shadow:
 0px 0px 0px 1px #aaa,
 1px 0px 0px 0px rgba(255,255,255,0.9) inset,
 0px 1px 2px rgba(0,0,0,0.2);
}

Для первого и последнего тега label мы создадим закругленные уголки:

.ff-container label.ff-label-type-all{
 border-radius: 3px 0px 0px 3px;
}
.ff-container label.ff-label-type-3{
 border-radius: 0px 3px 3px 0px;
}

Для каждой отмеченной радио-кнопки, мы создадим стили имитирующие эффект "нажатия":

.ff-container input.ff-selector-type-all:checked ~ label.ff-label-type-all,
.ff-container input.ff-selector-type-1:checked ~ label.ff-label-type-1,
.ff-container input.ff-selector-type-2:checked ~ label.ff-label-type-2,
.ff-container input.ff-selector-type-3:checked ~ label.ff-label-type-3{
 background: linear-gradient(top, #646d93 0%,#7c87ad 100%);
 color: #424d71;
 text-shadow: 0px 1px 1px rgba(255,255,255,0.3);
 box-shadow:
 0px 0px 0px 1px #40496e,
 0 1px 2px rgba(0,0,0,0.1) inset;
}

Так как у нас все наши элементы находятся на одном уровне, мы используем обобщенный родственный комбинатор (the general sibling combinator), который обозначается символом "тильда" (~). Селектор в ввиде input.ff-selector-type-3:checked ~ label.ff-label-type-3 значит, что элемент input.ff-selector-type-3:checked следует за элементом label.ff-label-type-3 в иерархии документа, исключая различные комментарии и т.п., и они обязательно имеют одного родителя. Этот «трюк» нам также позволит получить различные типы элементов в портфолио.

Элементы input могут быть скрыты, поскольку у нас есть label, которые будут делать всю работу:

.ff-container input{
 display: none;
}

Теперь давайте перейдем к элементам списка:

.ff-items{
 position: relative;
 margin: 0px auto;
 padding-top: 20px;
}

Ссылки и элементы span будeт иметь следующие стили:

.ff-items a{
 display: block;
 position: relative;
 padding: 10px;
 background: #fff;
 box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
 margin: 4px;
 width: 160px;
 height: 120px;
}
.ff-items a span{
 display: block;
 background: rgba(113,123,161, 0.9);
 font-style: italic;
 color: #fff;
 font-weight: bold;
 padding: 20px;
 position: absolute;
 bottom: 10px;
 left: 10px;
 width: 120px;
 height: 0px;
 overflow: hidden;
 opacity: 0;
 text-align: center;
 text-shadow: 1px 1px 1px #303857;
 transition: all 0.3s ease-in-out;
}
.ff-items a:hover span{
 height: 80px;
 opacity: 1;
}
.ff-items li img{
 display: block;
}

Когда мы наводим курсор мыши на ссылку, span будет появляются снизу, изменяя свою прозрачность.

Вот и все "общие" стили. Теперь давайте посмотрим стили для фильтрации элементов!

Пример 1

Пример 1

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

Мы добавим transition к элементу списка для создания непрозрачности:

.ff-items li{
 margin: 0px;
 float: left;
 opacity: 0;
 width: 188px;
 height: 148px;
 transition: opacity 0.6s ease-in-out;
}

Затем мы будем использовать обобщенный родственный комбинатор, чтобы установить непрозрачность для соответствующих пунктов:

.ff-container input.ff-selector-type-all:checked ~ .ff-items li,
.ff-container input.ff-selector-type-1:checked ~ .ff-items .ff-item-type-1,
.ff-container input.ff-selector-type-2:checked ~ .ff-items .ff-item-type-2,
.ff-container input.ff-selector-type-3:checked ~ .ff-items .ff-item-type-3{
 opacity: 1;
}

Так как у нас все радио-кнопки изначально отмечены, то все элементы будут изначально имеют непрозрачность равную 1.

Теперь, мы будем использовать селектор :not(), чтобы указать список элементов, которые не имеют выбранного класса и должны иметь прозрачность 0.1:

.ff-container input.ff-selector-type-1:checked ~ .ff-items li:not(.ff-item-type-1),
.ff-container input.ff-selector-type-2:checked ~ .ff-items li:not(.ff-item-type-2),
.ff-container input.ff-selector-type-3:checked ~ .ff-items li:not(.ff-item-type-3){
 opacity: 0.1;
}

Описания для этих элементов списка не должны показываться при наведении:

.ff-container input.ff-selector-type-1:checked ~ .ff-items li:not(.ff-item-type-1) span,
.ff-container input.ff-selector-type-2:checked ~ .ff-items li:not(.ff-item-type-2) span,
.ff-container input.ff-selector-type-3:checked ~ .ff-items li:not(.ff-item-type-3) span{
 display: none;
}

Это был первый пример. Давайте взглянем на следующий.

Пример 2

Пример 2

В этом примере мы сделаем выбранные элементы увеличенными, в то время как другие уменьшим и сделаем более прозрачными. Итак, давайте добавим transition к элементам списка:

.ff-items li{
 margin: 0px;
 float: left;
 width: 188px;
 height: 148px;
 transition: all 0.6s ease-in-out;
}

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

.ff-container input.ff-selector-type-1:checked ~ .ff-items .ff-item-type-1,
.ff-container input.ff-selector-type-2:checked ~ .ff-items .ff-item-type-2,
.ff-container input.ff-selector-type-3:checked ~ .ff-items .ff-item-type-3{
 opacity: 1;
 transform: scale(1.1);
}

Другие элементы портфолио мы будем уменьшать и применять к ним низкий уровень прозрачности:

.ff-container input.ff-selector-type-1:checked ~ .ff-items li:not(.ff-item-type-1),
.ff-container input.ff-selector-type-2:checked ~ .ff-items li:not(.ff-item-type-2),
.ff-container input.ff-selector-type-3:checked ~ .ff-items li:not(.ff-item-type-3){
 opacity: 0.1;
 transform: scale(0.5);
}

И мы опять будем скрывать описание для элементов, которые не выбраны:

.ff-container input.ff-selector-type-1:checked ~ .ff-items li:not(.ff-item-type-1) span,
.ff-container input.ff-selector-type-2:checked ~ .ff-items li:not(.ff-item-type-2) span,
.ff-container input.ff-selector-type-3:checked ~ .ff-items li:not(.ff-item-type-3) span{
 display:none;
}

Пример 3

Пример 3

Последний пример всего лишь эксперимент. Мы хотим сделать что-то немного более сложное здесь: при выборе типа, мы хотим масштабировать все элементы, уменьшив их, а затем увеличить только элементы с выбранным типом.

Мы хотим, чтобы невыбранные элементы исчезли, но так как мы не можем анимировать свойство display, мы используем одну маленькую хитрость: когда мы будем уменьшать элементы, мы изменим ширину и сделаем её равной 0.

Итак, давайте зададим изначально ширину списка равную 0:

.ff-items li{
 margin: 0px;
 float: left;
 height: 148px;
 width: 0px;
 transform: scale(0,0);
}

Когда выбран пункт "all", мы изменим масштаб равный 1 и ширину установим равную 188px:

.ff-container input.ff-selector-type-all:checked ~ .ff-items li{
 width: 188px;
 transform: scale(1,1);
 transition: transform 0.3s linear;
}

Помните,  что это состояние на начальном этапе, так как у нас "all" отмечено по умолчанию.

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

.ff-container input.ff-selector-type-1:checked ~ .ff-items .ff-item-type-1,
.ff-container input.ff-selector-type-2:checked ~ .ff-items .ff-item-type-2,
.ff-container input.ff-selector-type-3:checked ~ .ff-items .ff-item-type-3
{
 transition: transform 0.3s linear, width 0s linear 0.3s;
 animation: scaleUp 0.3s linear 0.4s forwards;
}
.ff-container input.ff-selector-type-1:checked ~ .ff-items li:not(.ff-item-type-1),
.ff-container input.ff-selector-type-2:checked ~ .ff-items li:not(.ff-item-type-2),
.ff-container input.ff-selector-type-3:checked ~ .ff-items li:not(.ff-item-type-3)
{
 animation: scaleDown 0.3s linear forwards;
}
@keyframes scaleUp {
 50% { width: 188px; transform: scale(0,0); }
 100% { width: 188px; transform: scale(1,1); }
}
@keyframes scaleDown {
 0% { width: 188px; transform: scale(1,1);}
 99% { width: 188px; transform: scale(0,0);}
 100% { width: 0px; transform: scale(0,0); }
}

Обратите внимание, что этот пример экспериментальный и он будет корректно работать только в браузерах, поддерживающих CSS анимацию. В Firefox 9.0.1 поведение не то, которое ожидалось (при наведении на label анимация срабатывает еще раз), но все работает в Авроре 11.0a2, так что может быть это баг браузера.

Скачать исходники

Перевод статьи Mary Lou с tympanus.net/codrops

Добавить комментарий


Защитный код
Обновить

Если вы заметили ошибку в тексте новости, пожалуйста, выделите её и нажмите Ctrl+Enter

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

Обновлено 10.01.2012 13:31
 

Апельсин-1

Голосование

Ваш любимый html-редактор?

Новые файлы

Шпаргалка по HTML5 Canvas

Archive - бесплатный кириллический шрифт

Шпаргалка по HTML5 атрибутам обработчиков событий

См. также

activecloud.ru

TisRef

Баннер
Система Orphus

Кто онлайн

Сейчас 133 гостей онлайн

Комментарии

Статистика