Доброго времени суток уважаемые читатели. На сегодняшний день уже многие знакомы с понятием адаптивный дизайн и я хочу поделиться интересной реализацией страницы портфолио с фильтрами.
HTML разметка
Указываем заголовок страницы, необходимые meta-теги, подключаем .css
и .js
файлы:
<!doctype html>
<html>
<head>
<title>Netcribe - Адаптивная страница портфолио с фильтрами</title>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta http-equiv="keywords" content="">
<meta http-equiv="description" content="">
<meta name="author" content="">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" href="">
<link rel="apple-touch-icon" href="">
<link rel="stylesheet" href="css/index.css" >
<link rel="stylesheet" href="css/media-queries.css">
<script src="http://yandex.st/jquery/1.8.3/jquery.min.js"></script>
<script src="js/index.js"></script>
</head>
Создаем тело страницы. В блоке <nav><ul> ... </ul></nav>
каждому элементу <li>
присваиваем идентификатор категории, по которому будем обращаться через JavaSript:
<!doctype html>
<body>
<div class="container">
<header>
<h1 class="title">
Адаптивная страница портфолио с фильтрами
</h1>
<nav>
<ul>
<li id="all">Все</li>
<li id="web">Сайты</li>
<li id="design">Дизайн</li>
<li id="infogrphic">Инфографика</li>
<li id="movie">Ролики</li>
</ul>
</nav>
</header>
<section class="work">
...
</section>
<footer></footer>
</div>
</body>
Создаем элементы портфолио <figure>
, классы которых равны идентификатору категории. Внутри элементов портфолио будет изображение и список определений <dl> <dt> <dd>
:
<figure class="web">
<a href="#">
<img src="images/1.png" alt="" />
<dl>
<dt>Категория</dt>
<dd>Описание работы</dd>
</dl>
</a>
</figure>
<!doctype html>
<html>
<head>
<title>Netcribe - Адаптивная страница портфолио с фильтрами</title>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta http-equiv="keywords" content="">
<meta http-equiv="description" content="">
<meta name="author" content="">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" href="">
<link rel="apple-touch-icon" href="">
<link rel="stylesheet" href="css/index.css" >
<link rel="stylesheet" href="css/media-queries.css">
<script src="http://yandex.st/jquery/1.8.3/jquery.min.js"></script>
<script src="js/index.js"></script>
</head>
<body>
<div class="container">
<header>
<h1>
Адаптивная страница портфолио с фильтрами
</h1>
<nav>
<ul>
<li id="all">Все</li>
<li id="web">Сайты</li>
<li id="design">Дизайн</li>
<li id="infogrphic">Инфографика</li>
<li id="movie">Ролики</li>
</ul>
</nav>
</header>
<section class="work">
<figure class="web">
<a href="#">
<img src="images/1.png" alt="" />
<dl>
<dt>Категория</dt>
<dd>Описание работы</dd>
</dl>
</a>
</figure>
<figure class="design">
<a href="#">
<img src="images/2.png" alt="" />
<dl>
<dt>Категория</dt>
<dd>Описание работы</dd>
</dl>
</a>
</figure>
<figure class="infogrphic">
<a href="#">
<img src="images/3.png" alt="" />
<dl>
<dt>Категория</dt>
<dd>Описание работы</dd>
</dl>
</a>
</figure>
<figure class="movie">
<a href="#">
<img src="images/4.png" alt="" />
<dl>
<dt>Категория</dt>
<dd>Описание работы</dd>
</dl>
</a>
</figure>
</section>
<footer></footer>
</div>
</body>
</html>
CSS
Стилизуем основные элементы-контейнеры:
body {
background: #dfdfdf url('https://www.netcribe.com/images/pattern.png');
padding: 0;
margin: 0;
}
.container {
width: 960px;
margin: 10px auto;
oveflow: hidden;
}
header {
text-align: center;
}
h1 {
font-family: Ubuntu;
font-size: 30px;
font-weight: 300;
}
Задаем стиль для навигационной панели:
nav ul {
list-style: none;
padding: 0;
margin: 50px 0;
text-align: center;
}
nav ul li {
display: inline;
cursor: pointer;
margin-right: 10px;
color: #666;
font-size: 12px;
transition: 0.3s;
-webkit-transition: 0.3s;
-moz-transition: 0.3s;
-o-transition: 0.3s;
-ms-transition: 0.3s;
}
nav ul li:hover {
color: #000;
}
nav ul li:last-child { /* Убираем margin у последнего элемента списка для корректного центрирования */
margin-right: 0;
}
nav ul li:after { /* Добавляем разделитель '/' */
margin-left: 10px;
content: '/';
color: #bbb;
}
nav ul li:hover:after {
color: #bbb;
}
nav ul li:last-child:after { /* Убираем разделитель '/' после последнего элемента списка */
content: '';
}
.current-li { /* Присваиваемый класс выбранному элементу категории */
color: #000;
}
Стилизуем элементы портфолио:
.work {
margin: 20px 0;
}
.work figure {
float: left;
margin: 20px;
width: 200px;
height: 200px;
background: #0296BA;
/* Используем webkit фильтр (подробнее на http://habrahabr.ru/post/155353/) */
-webkit-filter: sepia(0.4);
position: relative; /* Поскольку к <dl> применяется абсолютное позицианирование */
padding: 0 !important;
box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.5);
transition: 0.6s;
/* Анимация сортировки работ при выборе категории */
-webkit-transition: 0.6s;
-moz-transition: 0.6s;
-o-transition: 0.6s;
-ms-transition: 0.6s;
}
.work figure a img {
height: 100%;
width: 100%;
}
Описание к каждой работе в портфолио должно появляться при наведении на нее (тег <figure>
). Устанавливаем нулевую непрозрачность и абсолютное позицианирование для <dl>
:
.work figure a {
text-decoration: none;
}
.work figure a img {
height: 100%;
width: 100%;
}
.work figure dl {
opacity: 0;
position: absolute;
left: 0;
right: 0;
bottom: 0;
top: 0;
padding: 20px;
margin: 0;
background: rgba(0, 0, 0, 0.8);
color: white;
transition: 0.6s;
-webkit-transition: 0.6s;
-moz-transition: 0.6s;
-o-transition: 0.6s;
-ms-transition: 0.6s;
}
.work figure:hover dl {
opacity: 1;
}
.work figure dl dt {
text-transform: uppercase;
margin-bottom: 20px;
}
.work figure dl dd {
font-size: 12px;
}
Стилизуем классы .selected и .not-selected
, свойства которых описывают изменения в анимации элементов <figure>
при выборе категории.
.selected {
-webkit-filter: sepia(0) !important;
-webkit-transform: scale(1.05);
-moz-transform: scale(1.05);
-o-transform: scale(1.05);
-ms-transform: scale(1.05);
transform: scale(1.05);
}
.not-selected {
-webkit-transform: scale(0.75);
-moz-transform: scale(0.75);
-o-transform: scale(0.75);
-ms-transform: scale(0.75);
transform: scale(0.75);
-webkit-filter: grayscale(1) !important;
}
Selection и Scrollbar
Прошли те дни, когда было актуально стилизовать scrollbar в IE 5.5 и IE6 с помощью не стандартизированных W3C свойств вида scrollbar-base-color
. Хочется поделиться одной интересной особенностью webkit:
::selection {
background: #333;
color: #FFF;
}
::-webkit-scrollbar {
width: 9px;
}
::-webkit-scrollbar-track {
background:#eee;
border: thin solid lightgray;
box-shadow: 0px 0px 3px rgba(0, 0, 0, 0.1) inset;
}
::-webkit-scrollbar-thumb {
background:#999;
border: thin solid gray;
}
C помощью псевдо-селекторов ::-webkit-scrollbar; ::-webkit-scrollbar-track; ::-webkit-scrollbar-thumb;
мы простилизовали scrollbar в webkit, что похоже на скроллинг в Gmail. Учитывая количество пользователей Google Chrome, Safari, Yandex Browser мы можем смело применять эти свойства, так как это не останется незамеченным практически для половины аудитории Вашего сайта. Если я не ошибаюсь, то об этой полезности на хабре не рассказывалось, хотя данные префиксы поддерживаются с 2009 года. Подробно об этом пишет Cris Coyier на CSS Tricks.
Media Queries
965px или меньше
840 = (170+40)*4. Ширина .conteiner
равна сумме ширины и значений свойств margin-left и margin-right помноженных на 4 (элемента).
/* Старые мониторы, нетбуки, планшеты (в горизонтальном положении) */
@media only screen and (max-width: 965px) {
.container {
width: 840px;
}
.work figure {
width: 170px;
height: 170px;
}
}
860px или меньше
При этом разрешении в одной строке выводится три элемента — 720 = (200+40)*3.
/* Нетбуки, планшеты */
@media only screen and (max-width: 860px) {
.container {
width: 720px;
}
.work figure {
width: 200px;
height: 200px;
}
}
740px или меньше
600 = (160+40)*3. Добавим непрозрачность 0.5 что бы на устройствах с данным разрешением заметнее выглядели элементы с классом .not-selected:
/* Планшеты и телефоны */
@media only screen and (max-width: 740px) {
.container {
width: 600px;
}
.work figure {
width: 160px;
height: 160px;
}
.not-current {
opacity: 0.5;
}
}
610px или меньше
460 = (160+70)*2
/* Телефоны (в горизонтальном положении) и Планшеты (в вертикальном положении) */
@media only screen and (max-width: 610px) {
.container {
width: 460px;
}
.work figure {
margin: 20px 35px;
}
}
480px или меньше
320 = 200 + 120
/* Телефоны (в горизонтальном положении) */
@media only screen and (max-width: 480px) {
.container {
width: 320px;
}
.work figure {
width: 200px;
height: 200px;
margin: 20px 60px;
}
}
JavaScript — jQuery
Все просто — манипулируем классами:
- Создаем обработчик события при клике на категории
nav > li
- У всех элементов, где класс совпадает с идентификатором выбранной категории удаляем класс .not-selected и добавляем .selected.
- Удаляем класс .corrent-li и добавляем .current-li выбранной категории.
- Для всех работ не входящих в выбранную категорию удаляем класс .selected и присваиваем .not-selected
function scaleDown() { // Заменяем классы у выделенных элементов, и удаляем класс у текущей категории
$('.work > figure').removeClass('selected').addClass('not-selected');
$('nav > ul > li').removeClass('current-li');
}
function show(category) { // Добавляем класс к категории, меняем классы у выбранных работ
scaleDown();
$('#' + category).addClass('current-li');
$('.' + category).removeClass('not-selected');
$('.' + category).addClass('selected');
if (category == "all") { // Если выбраны все работы
$('nav > ul > li').removeClass('current-li');
$('#all').addClass('current-li');
$('.work > figure').removeClass('selected, not-selected');
}
}
$(document).ready(function(){
$('#all').addClass('current-li');
$("nav > ul > li").click(function(){
show(this.id);
});
});
Спасибо всем за внимание.
Автор: ilusha_sergeevich