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

Как обычно, давайте сначала посмотрим на нашу демонстрацию (просмотрите все примеры):

Начнем с  .card-wrapperэлемента, который будет включать все карты. 

Каждая карта, представленная cardклассом, будет содержать .card-innerэлемент. Внутри этого элемента мы поместим содержимое целевой карты:

1
2
3
4
5
6
7
8
9
<div class="card-wrapper">
  <div class="card">
    <div class="card-inner">
      <h3 class="card-title">...</h3>
      <div class="card-body">...</div>
    </div>
     
    <!-- more cards here -->
  </div>

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

  • card-top-left
  • card-top-right
  • card-bottom-left
  • card-bottom-right
  • card-diagonal-from-right
  • card-diagonal-from-left
  • card-rotate
  • card-perspective
  • card-origin

Когда разметка будет готова, мы настроим несколько переменных CSS и сбросим стили:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
:root {
  --body-text-color: #5c5957;
  --body-bg-color: #e2d9d5;
  --card-border-color: #e2d9d5;
  --card-bg-color: #fff;
  --offset-before: 8px;
  --offset-after: 16px;
}
 
*,
*::before,
*::after {
  box-sizing: border-box;
}
 
body {
  color: var(--body-text-color);
  background: var(--body-bg-color);
}

Чтобы создать эффект суммирования, мы собираемся использовать псевдоэлементы. Для каждой карты мы определим  ::beforeи ::afterпсевдо-элементы и абсолютно позиционировать их по отношению к материнской карте. 

Далее мы переместим их из исходного положения с помощью transformсвойства. В течение первых шести примеров в демонстрационном примере, количество этого репозиция будет определяться offset-beforeи offset-afterпеременными.

Следует также отметить, что мы даем  z-index: 1 всем  .card-inner элементам, чтобы они всегда располагались поверх своих псевдоэлементов.

Вот макет карты, когда значение  offset-beforeпеременной составляет 8px, а значение offset-afterпеременной - 16px:


А вот схема, когда эти переменные удваивают свои значения:


Требуемые стили CSS для создания макета карты:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/*VARIABLES HERE*/
 
.card {
  position: relative;
  cursor: pointer;
  max-width: 400px;
  margin: 60px auto;
}
 
.card::before,
.card::after {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}
 
.card::before,
.card::after,
.card .card-inner {
  background-color: var(--card-bg-color);
  border: 1px solid var(--card-border-color);
  border-radius: 5px;
  transition: transform 0.3s;
}
 
.card::before,
.card-inner {
  z-index: 1;
}
 
.card-inner {
  position: relative;
  padding: 3rem;
}

Как уже говорилось, каждая карта включает второй класс, который обрабатывает свои начальные смещения вместе с эффектом наведения. Например, вот дополнительные правила, которые действуют для карты, содержащей card-top-leftкласс:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
/*CUSTOM VARIABLES HERE*/
 
.card-top-left::before {
  transform: translate(
    calc(-1 * var(--offset-before)),
    calc(-1 * var(--offset-before))
  );
}
 
.card-top-left::after {
  transform: translate(
    calc(-1 * var(--offset-after)),
    calc(-1 * var(--offset-after))
  );
}
 
.card-top-left:hover::before,
.card-top-left:hover::after,
.card-top-left:hover .card-inner {
  transform: translate(calc(-1 * var(--offset-before)), 0);
}