Адаптивная вёрстка, урок третий. Сетка из блоков

В этом уроке мы рассмотрим создание макета страницы портфолио на основе плиточной сетки. Для создания сетки используются библиотеки Masonry и imagesLoaded Dave DeSandro. Изображения, представленные в демо-версии, взяты с сайта Unsplash.com.

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

Перейти на страницу-портфолио

1. Метатеги и раздел <head>

1) Раздел <head> должен содержать ссылки на необходимые файлы — используемые шрифты и таблицу стилей.

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Галерея Masonry</title>
  <link href="https://fonts.googleapis.com/css?family=Muli:400,600,700|Radley" rel="stylesheet">
  <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css" rel="stylesheet">
  <link href="style.css" rel="stylesheet">
</head>
<body>

2. Шапка страницы

Шапка страницы — раздел <header> содержит следующие элементы-контейнеры:
— логотип <div class="logo">;
— главное меню <ul id="menu">;
— кнопку для показа/скрытия главного меню <div class="burger">.

<header>
  <div class="container">
    <div class="header-row">
      <div class="logo">
        <a href="">
          <span class="logo-name">Helen Parker</span>
          <span class="logo-description">
            <span>personal photographer</span>
          </span>
        </a>
      </div>
      <ul id="menu">
        <li>
          <a href="">Blog</a>
        </li>
        <li class="current">
          <a href="">Portfolio</a>
        </li>
        <li>
          <a href="">About</a>
        </li>
      </ul>
      <div class="burger">
        <span></span>
      </div>
    </div>
  </div>
</header>

3. Сетка с фотографиями

Основная часть страницы состоит из блоков с фотографиями, для которых задан фильтр grayscale, придающий им эффект черно-белых фотографий. При наведении этот эффект исчезает.

<div class="main">
  <div class="container">
    <div class="row">
      <div class="grid">
        <div class="grid-item">
          <a class="grid-link" href="">
            <img class="grid-img" src="images/image-1.jpg" alt=""/>
          </a>
        </div>
        <div class="grid-item">
          <a class="grid-link" href="">
            <img class="grid-img" src="images/image-2.jpg" alt=""/>
          </a>
        </div>
        <div class="grid-item">
          <a class="grid-link" href="">
            <img class="grid-img" src="images/image-3.jpg" alt=""/>
          </a>
        </div>
        <div class="grid-item">
          <a class="grid-link" href="">
            <img class="grid-img" src="images/image-4.jpg" alt=""/>
          </a>
        </div>
        <div class="grid-item">
          <a class="grid-link" href="">
            <img class="grid-img" src="images/image-5.jpg" alt=""/>
          </a>
        </div>
        <div class="grid-item">
          <a class="grid-link" href="">
            <img class="grid-img" src="images/image-6.jpg" alt=""/>
          </a>
        </div>
        <div class="grid-item">
          <a class="grid-link" href="">
            <img class="grid-img" src="images/image-7.jpg" alt=""/>
          </a>
        </div>
        <div class="grid-item">
          <a class="grid-link" href="">
            <img class="grid-img" src="images/image-8.jpg" alt=""/>
          </a>
        </div>
        <div class="grid-item">
          <a class="grid-link" href="">
            <img class="grid-img" src="images/image-9.jpg" alt=""/>
          </a>
        </div>
        <div class="grid-item">
          <a class="grid-link" href="">
            <img class="grid-img" src="images/image-10.jpg" alt=""/>
          </a>
        </div>
      </div>
    </div>
  </div>
</div>

4. Подвал сайта

Нижний колонтитул содержит сведения о копирайте и ссылки на социальные сети.

<footer>
  <div class="container">
    <div class="footer-row">
      <div class="footer-col">
        <p>Copyright © 2018 Helen Parker</p>
      </div>
      <div class="footer-col">
        <div class="social-icons-wrapper">
          <a class="social-icon" target="_blank" href=""><i class="fa fa-facebook"></i></a>
          <a class="social-icon" target="_blank" href=""><i class="fa fa-twitter"></i></a>
          <a class="social-icon" target="_blank" href=""><i class="fa fa-google-plus"></i></a>
        </div>
      </div>
    </div>
  </div>
</footer>

5. Файл style.css

* {
  box-sizing: border-box;
  padding: 0;
  margin: 0;
}
body {
  font-family: 'Muli', sans-serif;
  font-size: 14px;
  line-height: 1.5;
  color: #19121e;
  background-color: white;
}
ul {
  list-style: none;
}
a {
  text-decoration: none;
  outline: none;
}
.container {
  width: 100%;
  max-width: 1120px;
  padding: 0 10px;
  margin: 0 auto;
}
.row {
  margin: 0 -10px;
}

/*************************************************************/
/* HEADER                                                    */
/*************************************************************/
header {
  margin-bottom: 20px;
}
.header-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 20px 0;
  position: relative;
  border-bottom: 2px solid #d9d9d9;
}
.logo-name {
  display: block;
  font-size: 26px;
  line-height: 1;
  font-family: 'Radley', serif;
  text-transform: uppercase;
  color: #19121e;
}
.logo-description {
  position: relative;
  display: block;
  text-align: right;
  font-size: 10px;
  text-transform: uppercase;
  color: #a1787e;
}
.logo-description:before {
  content: "";
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  height: 1px;
  background-color: #a1787e;
  z-index: -1;
}
.logo-description span {
  padding-left: 10px;
  background-color: white;
}
#menu {
  position: absolute;
  top: calc(100% + 1px);
  left: 0;
  right: 0;
  z-index: 10;
  visibility: hidden;
  opacity: 0;
  background-color: white;
  transition: .3s linear;
}
#menu.show {
  visibility: visible;
  opacity: 1;
}
#menu li a {
  display: block;
  padding: 10px 0;
  position: relative;
  color: #19121e;
  font-size: 18px;
}
#menu li.current a {
  color: #a1787e;
}
.burger {
  position: relative;
  width: 28px;
  height: 19px;
  cursor: pointer;
}
.burger span {	
  position: absolute;
  top: 8px;
  width: 28px;
  height: 3px;
  background-color: #19121e;
  transition: background-color .3s ease-in-out;
}
.burger span:before,
.burger span:after {
  content: "";
  position: absolute;
  width: 28px;
  height: 3px;
  background-color: #19121e;
  transform: rotate(0deg);
  transition: background-color .3s ease-in-out, 
  transform .4s ease-in-out, top .4s ease-in-out;
}
.burger span:before {
  top: -8px;
}
.burger span:after {
  top: 8px;
}
.burger.close span {
  background-color: transparent;
}
.burger.close span:before {
  background-color: #a1787e;
  transform: rotate(45deg);
  top: 0;
}
.burger.close span:after {
  background-color: #a1787e;
  transform: rotate(-45deg);
  top: 0;
}

/*************************************************************/
/* PORTFOLIO GRID                                            */
/*************************************************************/
.grid {
  margin-bottom: 20px;
}
.grid-item {
  width: 100%;
  padding: 10px; 
}
.grid-item a {
  display: block;
}
.grid-item img {
  display: block;
  width: 100%;
  -webkit-filter: grayscale(100%);
  filter: grayscale(100%);
  transition: .5s ease-in-out;
}
.grid-item a:hover img {
  -webkit-filter: grayscale(0%);
  filter: grayscale(0%);
}

/*************************************************************/
/* FOOTER                                                    */
/*************************************************************/
.footer-row {
  padding: 20px 0;
  border-top: 2px solid #d9d9d9;
}
.footer-col {	
  padding: 0 10px; 
}
.footer-col:first-child {
  text-align: center;
}
.social-icons-wrapper {
  display: flex;
  justify-content: center;
  align-items: center;
  margin-top: 20px;
}
.social-icon { 
  display: block;
  width: 24px;
  height: 24px;
  line-height: 24px;
  border-radius: 50%;
  margin-left: 12px;
  text-align: center;
  font-size: 15px;
  color: #a1787e;
  background-color: rgba(20,20,20,0);	
  transform: scale(1);
  transition: .3s linear;
}
.social-icon:hover {
  transform: scale(1.2);
  background: #a1787e;
  color: #fff;
}

/*************************************************************/
/* MEDIA QUERIES                                             */
/*************************************************************/
@media (min-width: 480px) {
  .grid,
  .footer-row {
    display: flex;
  }
  .grid-item,
  .footer-col {
    width: 50%;
  }
  .social-icons-wrapper {
    justify-content: flex-end;
    margin-top: 0;
  }
  .footer-col:first-child {
    text-align: left;
  }
}
@media (min-width: 768px) {
  .grid-item {
    width: 33.33333333333333%;
  }
  .burger {
    display: none;
  }
  .header-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
  }
  #menu {
    display: flex;
    position: static;
    visibility: visible;
    opacity: 1;
  }
  #menu li {
    padding-left: 40px;
  }
  #menu li a {
    padding: 0;
  }
  #menu li a:before {
    content: "";
    position: absolute;
    bottom: -4px;
    right: 0;
    left: auto;
    width: 0;
    height: 1px;
    z-index: 2;
    background-color: #19121e;
    transition: .25s cubic-bezier(.694,.048,.335,1) .15s;
  }
  #menu li a:hover:before,
  #menu li.current a:before {
    width: 100%;
    left: 0;	
  }
  #menu li.current a:before {
    background-color: #a1787e;
  }
}

6. Скрипты

Для полноценной работы нужно подключить следующие скрипты:

  <script src="js/jquery-2.2.4.min.js"></script>
  <script src="js/imagesloaded.min.js"></script>
  <script src="js/masonry.min.js"></script>
  <script src="js/main.js"></script>
</body>
</html>

Проблема с накладыванием изображений сетки решается с помощью плагина imagesloaded. Он определяет, когда изображение загружено и после этого строит сетку Masonry.

6.1. Файл main.js

(function ($) {
  $(window).on("load", function () {
    var masonryGrid = $(".grid");
    masonryGrid.imagesLoaded(function () {
      masonryGrid.masonry({
        itemSelector: ".grid-item",
        percentPosition: true
      });
    });
  });
  $(document).on("click", ".burger", function () {
    $(".burger").toggleClass("close");
    $("#menu").toggleClass("show");
  });
})(jQuery);

Поделиться: