Центрирование блока с учётом тени
С помощью CSS можно легко "нарисовать" контейнер в виде стопки бумаги, задав для него тень. Но при выравнивании каким-либо способом тень не учитывается – это не так заметно на широком экране ПК, но очень заметно на мобильных устройствах. На этом сайте я применил подобный эффект на странице Мои музыкальные сочинения и в статье Нотный редактор MuseScore. Для примера я создам такой блок в виде стопки бумаги с тремя листами и при центрировании тень пока учитывать не буду:
Если приглядеться, центрирован только первый лист. Тени, образующие два других листа, смещены вправо и вниз. Если это не очень заметно, посмотрите на телефоне или в инспекторе браузера или просто сузив окно браузера. Вот Html и CSS:
1
2
3
<div id="shadow-container">
<div class="block">Я – блок с тенью</div>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#shadow-container {
background-color: #262626;
display: flex;
justify-content: center;
align-items: center;
height: 400px;
}
.block {
display: flex;
justify-content: center;
align-items: center;
width: 200px;
height: 200px;
background-color: white;
box-shadow: red 0px 0px 0px 2px inset,
white 14px 14px 0px -2px,
green 14px 14px,
white 28px 28px 0px -2px,
blue 28px 28px;
}
Поясню что я здесь написал. Сначала я создал внешний flex-контейнер #shadow-container
и задал для него justify-content: center;
и align-items: center;
для выравнивания вложенного в него блока с тенью .block
соответствено по горизонтали и вертикали. Для блока .block
я также задал display: flex;
, justify-content: center;
и align-items: center;
, но лишь для того, чтобы выровнять текст "Я – блок с тенью" по центру и к делу это не относится как и другие стили, которые я не упомянул. Самое главное здесь – это составная тень box-shadow
. Для первой тени (строка 16) указан параметр inset
, указывающий на то, что тень является внутренней. В данном случае будет создана тонкая граница красного цвета. Для всех остальных теней параметр не указан – это говорит о том, что они являются внешними. В строках 17 и 19 создаётся белая тень с тонкой цветной границей. Первым параметром здесь указывается цвет тени, два следующих параметра – смещение по горизонтали и вертикали соответственно. Следующий параметр – радиус размытия. Если значение этого параметра равно нулю, край тени будет жёстким, то есть без размытия. Последний параметр -2px – это размер растушёвки (spread-radius), – это сужает белую тень на 2px и тем самым создаёт тонкую цветную границу за счёт отступа от краёв низлежащей тени.
Вообще параметры тени рекомендуют указывать в таком порядке: box-shadow: none|h-offset v-offset blur spread color |inset|initial|inherit;
и согласно этой рекомендации можно было бы записать так:
1
2
3
4
5
6
7
.block {
box-shadow: 0px 0px 0px 2px red inset,
14px 14px 0px -2px white,
14px 14px green,
28px 28px 0px -2px white,
28px 28px blue;
}
Но для таких параметров как color
и inset
порядок может быть произвольным. Главное, чтобы все числовые параметры имели строгий порядок: h-offset (смещение по горизонтали), v-offset (смещение по вертикали), blur-radius (радиус размытия), spread-radius (размер растушёвки). Параметры смещения являются обязательными, остальные параметры могут не указываться. Ключевое слово none
(box-shadow: none;
) отключает тень.
Итак, чтобы выровнять блок с учётом тени, можно просто задать внутренние отступы для #shadow-container
справа и снизу, поскольку тень распространяется в этих направлениях. Величина отступа – это величина смещения по осям X и Y последней тени, то есть 28px:
1
2
3
4
5
6
7
8
9
#shadow-container {
background-color: #262626;
display: flex;
justify-content: center;
align-items: center;
height: 400px;
padding-right: 28px;
padding-bottom: 28px;
}
И вот что у меня получилось:
На сайте я сделал именно так, но можно также вместо отступов воспользоваться свойством transform: translate()
, задав его для самого блока .block
, которое сдвинет его по оси X и Y (то есть влево и вниз), поскольку значения отрицательные, на половину величины смещения последней тени, то есть 14px:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#shadow-container {
background-color: #262626;
display: flex;
justify-content: center;
align-items: center;
height: 400px;
}
.block {
display: flex;
justify-content: center;
align-items: center;
width: 200px;
height: 200px;
background-color: white;
box-shadow: red 0px 0px 0px 2px inset,
white 14px 14px 0px -2px,
green 14px 14px,
white 28px 28px 0px -2px,
blue 28px 28px;
transform: translate(-14px, -14px);
}
И напоследок пример, иллюстрирующий всё вышесказанное: