Создаем адаптивную страницу портфолио с фильтрами

в 16:44, , рубрики: css, css3, html5, responsive design, адаптивная вёрстка, веб-дизайн, Веб-разработка, метки: , , ,

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

Netcribe
ДЕМО

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>
Конечный HTML код

<!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

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js