Всем привет!

Давненько, я ничего не писал про jQuery, все как-то руки не доходили, хотя много интересных скриптов пишется в проектах. Так вот о чем я: столкнулся с такой задачей: Есть 5 элементов-товаров ширина, которых тянется (ресайзится) на всю ширину обертки, нужно сделать, чтобы при ширине обертки меньше чем 1200 пикселей количество элементов-товаров становилось 4, в обратном случае количество элементов-товаров должно становится 5. Проще говоря смотрится это очень эффектно да и удобно. Решением этой задачи и займемся сечас.

Для общего представления, как будет выглядеть элемент статьи/товара/услуги посмотреть на картинку ниже:

Скрываем последний элемент в строке, при изменении окна браузера

Для старта понадобиться html-каркас странички, я беру его отсюда, и разметка строки товаров.

HTML разметка строки товаров

<div class="container">
  <div class="one_row">

    <!-- Таких элементов будет 5 -->
    <div class="grid_5">
      <a href="#" class="prod_item">
        <div class="prod_thumb">
          <img src="some_img.jpg" alt="" />
          <span class="prod_arrow"><span></span></span>
        </div>
        <span class="prod_title">Тут название товара</span>
      </a>
    </div>
	
  </div>
</div>

Итак, у нас есть общий контейнер .container, который тянется. Есть строка .one_row, которая содержит товары/услуги/статьи. И есть соответственно 5 контейнеров .grid_5, для услуг/товаров — в демо-примере будут статьи.

Распишу поподробней про разметку товара:

  • Ссылка-контейнер .prod_item
  • Бокс для картинки .prod_thumb
  • Двойная стрелка для бокса картинки .prod_arrow
  • Название товара .prod_title

Забыл сказать, что когда элементов в строке станет 4, то строке добавится сласс .col_4.

Я думаю что с разметкой более-менее разобрались, теперь давайте окунемся в правила CSS.

Стилизация товаров/услуг/статей

Как Вы могли убедиться, выше я описал порядочное к-во классов, которым нужно задать стили. Кстати забыл упомянуть, что сброс стилей, можно взять здесь. Начнем с общих правил:

body {
  min-width: 1000px;
}
.container {
  margin: 0 auto;
  max-width: 1320px;
  padding: 0 20px;
}
.one_row {
  margin-left: -20px;
}
.one_row:before,
.one_row:after {
  content: " ";
  display: table;
}
.one_row:after {
  clear: both;
}
.ie7 .one_row {
  position: relative;
  zoom: 1;
}
.grid_5 {
  width: 20%;
  float: left;
}
.one_row.col_4 .grid_5 {
  width: 25%;
}
.ie7 .grid_5 {
  width: 19.8%;
}
.ie7 .one_row.col_4 .grid_5 {
  width: 24.8%;
}
.hidden {
  display: none;
}

Пару слов о общих стилях.

В первую очередь напомню, что строка с товарами/услугами/статьями у нас отзывчивая (то есть тянется по ширине окна браузера), а значит для body мы задали минимальную ширину [min-width] 1000 пикселей, а для основного контейнера .conteiner задаем максимальную ширину [max-width] 1320 пикселей и выровняли его по центру окна. Дальше проще.

Строке .one_row с помощью псевдоэлементов :before и :after задаем сброс обтекания, почему? — потому что боксы .grid_5 выравниваются в ряд обтеканием float и чтобы все было четко, обтекание нужно сбросить. Блокам .grid_5 помимо обтекания задаем ширину 20%, также уточняем что если блоков в строке будет 4, то ширина их будет 25%; тут тоже есть важный момент ИЕ7 реально подергивается при ресайзе таких процентных широт, поэтому для .ie7 нужно указывать ширину поменьше, в данном случае это 24.8% и 19.8% — можете попробовать уменьшить только на 0.1%. И еще мы задаем cтроке .one_row отрицательный отступ слева — это отступы между блоками товаров/услуг/статей.

Еще есть класс .hidden — он будет добавляться последнему элементу строки и стилей для него аж одна строчка display: none;. Вот в общем и все объяснения для общих стилей.

Приступим к стилизации самих блоков товаров/услуг/статей:

.prod_item {
  text-decoration: none;
  display: block;
  margin-left: 20px;
}
.prod_title {
  display: block;
  font: bold 14px Arial;
  color: #336699;
  text-align: center;
}
.prod_thumb {
  border: 7px solid #ff0000;
  position: relative;
  height: 150px;
  margin-bottom: 20px;
  text-align: center;
}

В принципе ничего особенного не написал, но разжую)

Контейнер-ссылку задаем как блочный элемент и указываем отступ слева 20px — для себя Вы можете задать больший отступ, ничего не поламается, только не забывайте тогда указывать аналогичный отрицательный отступ слева у строки .one_row. Названию задаем цвет, ширину, шрифт. Контейнеру картинки задаем рамку шириной 7px, высоту (также можете указать ту которая Вам нужна), выравнивание картинок по центру, отступ снизу и указываем что позиция блока относительная — это указывается для, того, чтобы спозиционировать стрелочки контейнера картинки.

А теперь добавим стилей стрелкам. Думаю, всем известно, что стелочки можно делать средствами CSS, а не картинками, ну а кому неизвестно, то делаются любые стрелки с помощью правила border, В самом начале статьи я показывал картинку, как будет выглядеть товар/услуга/статья — вокруг картинки идет рамка а внизу рамки стрелочка, но чтобы ее сделать нужно нарисовать две стрелочки: одну красную, другую белую. Этим и займемся:

.prod_arrow {
  position: absolute;
  width: 0;
  height: 0;
  bottom: -20px;
  z-index: 10;
  left: 50%;
  margin-left: -19px;

  border-top: 20px solid rgba(255,0,0,1);
  border-left: 20px solid rgba(255,0,0,0);
  border-right: 20px solid rgba(255,0,0,0);
  border-bottom: 0px solid rgba(255,0,0,0);
}
.prod_arrow span {
  position: absolute;
  width: 0;
  height: 0;
  top: -20px;
  left: -10px;
  z-index: 12;

  border-top: 10px solid rgba(255,255,255,1);
  border-left: 10px solid rgba(255,255,255,0);
  border-right: 10px solid rgba(255,255,255,0);
  border-bottom: 0px solid rgba(255,255,255,0);
}
.ie7 .prod_arrow,
.ie8 .prod_arrow {
  border-top: 20px solid #ff0000;
  border-left: 20px solid transparent;
  border-right: 20px solid transparent;
  border-bottom: 0px solid transparent;
}
.ie7 .prod_arrow span,
.ie8 .prod_arrow span {
  border-top: 10px solid #ffffff;
  border-left: 10px solid transparent;
  border-right: 10px solid transparent;
  border-bottom: 0px solid transparent;
}

Как Вы могли заметить первую стрелку я позиционирую абсолютно относительно контейнера картинки и задаю ей размер: 20px высоту и 20px скосы по бокам ну и цвет красный. Это очень важно, цвет нужно задавать в формате rgba() потому, что Mozilla Firefox к стандартному заданию цвета типа #ff0000 относится плохо и дорисовывает вокруг стрелки рамку и выглядит это ужасно. Естественно ИЕ7-8 не понимат rgba() поэтому для них отдельно указываем цвет стрелок. Вторую стрелочку (белую) позиционируем абсолютно относительно первой стрелки, то есть накладываем ее поверх первой. Вот и все тайны стилизации.

jQuery скрипт

С написанием стилей покончено, осталось написать небольшой (минимальный) скрипт, который возьмет управление нашей задачей, под свой контроль. Напомню задачу: при ширине обертки меньше чем 1200 пикселей количество элементов-товаров становится 4, в обратном случае количество элементов-товаров становится 5.

Суть задачи ясна, для решения воспользуемся условием: Если ширина тела сайта меньше чем 1200px, то добавляем строке класс .col_4, находим в ней последний элемент добавляем ему класс .hidden; в противном случае: удаляем у строки класс .col_4 и у последнего элемента также удаляем класс .hidden. Напишем, что проговорили:

(function($) {

  if($('body').width() < 1200){
    $('.one_row').addClass('col_4').find('.grid_5:last').addClass('hidden');
  } else {
    $('.one_row').removeClass('col_4').find('.grid_5:last').removeClass('hidden');
  }

})(jQuery);

Практически идеально, но главное дальше. По сути мы напсиали всего лишь условие, которое сработает при загрузке страницы, а после ресайза ничего не измениться, поэтому нужно воспользоваться функцией resize() и слегка дописать скрипт, вот так:

(function($) {

  if($('body').width() < 1200){
    $('.one_row').addClass('col_4').find('.grid_5:last').addClass('hidden');
  } else {
    $('.one_row').removeClass('col_4').find('.grid_5:last').removeClass('hidden');
  }

  $(window).resize(function(){
    if($('body').width() < 1200){
      $('.one_row').addClass('col_4').find('.grid_5:last').addClass('hidden');
    } else {
      $('.one_row').removeClass('col_4').find('.grid_5:last').removeClass('hidden');
    }
  });


})(jQuery);

Вот теперь все идеально! Скрипт достаточно простой да и все объяснения кроятся в постановке задачи. Использование цепных функций jQuery значительно уменьшает скрипт.

Результат

Результат Вы можете увидеть на странице демонстрации (напомню, что я уже писал статью как сделать демонстрации уроков в WordPress) а также можете скачать исходники ниже:

Скрипт работает во всех популярных браузерах и в IE7+, в IE6 не проверял, так как я с ним не работаю, и Вам не советую)

Заключение

Как оказалось, сложные вещи сделать простыми, можно! Спасибо за внимание! Критику, пожелания оставляйте в комментариях, также помните, что хорошо поделиться статьей в соц. сетях!

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


Комментарии
  1. Alex

    логично задачу дорешать, доведя
    количество блоков до 1 дабы не было горизонтальной прокрутки

  2. JAH

    Alex, задача так не стояла, да и тянулся макет только в определенных пределах

  3. Йошкин

    Через медиа запросы проще было бы?

  4. Саша

    Пытался по такому принципу построить мобильную версию сайта, что бы элементы уменьшались в соответствии с расширением экрана, но что то пошло не так(((