Используйте flexbox и поддерживайте соотношение сторон 1:1, даже если контент имеет размер по-разному
Есть много вопросов о SO о поддержании соотношения сторон элемента (с flexbox или без). Однако моя проблема несколько отличается, поскольку я хочу переопределить соотношение сторон дочернего элемента изображения:
- Убедитесь, что изображение полностью покрывает элемент (
object-fit: cover
)
- Убедитесь, что элемент равен 1:1 (т.е. идеальный круг)
- Убедитесь, что переполненное изображение скрыто
Другими словами, изображение должно вести себя так, как если бы это был фон элемента (я не могу использовать их в качестве фоновых изображений), из которых соотношение сторон всегда 1:1 и отзывчивое.
В приведенном ниже примере все работает отлично, за исключением того, что элементы <a>
адаптируются к их потомкам изображения. Но я хочу, чтобы они поддерживали соотношение 1:1, чтобы получить идеальные круги. (Средняя часть первой строки должна быть больше остальных).
HTML не может измениться, но я могу использовать современные CSS-свойства, такие как object-fit и flexbox. (Пока поддерживаются последние версии Chrome/Firefox.)
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.img-gallery {
background: #fafafa;
padding: 24px;
min-width: 320px;
width: 90%;
margin: 0 auto;
}
.img-gallery .row {
display: flex;
flex-wrap: nowrap;
justify-content: space-around;
align-items: center;
}
.img-gallery a {
display: block;
text-decoration: none;
background-image: linear-gradient(60deg, #004494 0%, #7db9e8 78%, #c2dfed 100%);
overflow: hidden;
border-radius: 50%;
padding: 3px;
flex: 1;
margin: 0 24px;
transition: padding 200ms;
}
.img-gallery a:hover,
#s_country .img-gallery .row:first-of-type a:nth-child(2):hover {
padding: 0;
}
.img-gallery a:hover span {
transform: scale(1.25);
}
.img-gallery .row:first-of-type a:not(:nth-child(2)) {
width: 30%;
width: calc((60% - 96px) / 2);
}
.img-gallery .row:first-of-type a:nth-child(2) {
flex: 2;
padding: 4px;
}
.img-gallery span {
width: 100%;
height: 100%;
display: block;
border-radius: 50%;
position: relative;
overflow: hidden;
transition: transform 250ms;
z-index: 2;
}
.img-gallery img {
width: 100%;
height: 100%;
object-fit: cover;
}
.img-gallery span::before {
content: "";
background-image: linear-gradient(60deg, transparent 48%, #ffc5e7 100%);
width: 100%;
height: 100%;
position: absolute;
z-index: 2;
border-radius: 50%;
opacity: .72;
}
<div class="img-gallery">
<div class="row">
<a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/b3/9c/54/b39c54776074d07ee0b567826768730a.jpg" id="img-1-3"></span></a>
<a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/d6/df/51/d6df512a2f15f517767b4d82d2d97a4c.jpg" id="img-1-4"></span></a>
<a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/ec/a9/dd/eca9dd106a04cdbee399870252ef711f.jpg" id="img-1-5"></span></a>
</div>
<div class="row">
<a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/7d/01/19/7d0119a2fec989e208f288326c7cad0f.jpg" id="img-1-6"></span></a>
<a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/d8/c3/32/d8c332d09b03673845b2e92a48816233.jpg" id="img-1-7"></span></a>
<a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/88/3b/dd/883bddab14168f5f0807fec021002d8d.jpg" id="img-1-8"></span></a>
</div>
<div class="row">
<a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/8e/4f/bb/8e4fbb89b155d15521b80d1baf9290d1.jpg" id="img-1-9"></span></a>
</div>
</div>
Ответы
Ответ 1
Чтобы поддерживать соотношение сторон реагирующих элементов, вы можете использовать технику отладки .
Обратите внимание, что вы не должны использовать проценты для заполнения дна/вершины для гибких детей, см. Здесь для получения дополнительной информации.
Вы можете создать сетку реагирующих квадратов и добавить радиус границы, чтобы сделать их кругами.
Для изображений свойство object-fit: cover;
делает именно то, что вам нужно: сохранить исходное соотношение сторон изображения и полностью покрыть элемент.
Я изменил первое изображение на ландшафтное изображение, чтобы показать, что эта техника работает и с этими.
Вот пример того, как вы можете достичь своей цели (я лишил некоторые из ваших CSS, чтобы демонстрация была простой):
*,*::before,*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.img-gallery {
background: #fafafa;
padding: 24px;
min-width: 320px;
width: 90%;
margin: 0 auto;
}
.img-gallery .row {
display: flex;
flex-wrap: nowrap;
justify-content: space-around;
align-items: center;
}
.img-gallery a {
display: block;
position:relative;
text-decoration: none;
background-image: linear-gradient(60deg, #004494 0%, #7db9e8 78%, #c2dfed 100%);
overflow: hidden;
border-radius: 50%;
flex: 1;
margin: 24px;
}
.img-gallery a::before{
content:'';
display:block;
padding-bottom:100%;
}
.img-gallery .row:first-of-type a:not(:nth-child(2)) {
width: 30%;
width: calc((60% - 96px) / 2);
}
.img-gallery .row:first-of-type a:nth-child(2) {
flex: 2;
}
.img-gallery span {
position:absolute;
top:3px;left:3px;right:3px;bottom:3px;
border-radius: 50%;
overflow: hidden;
transition: transform 250ms;
}
.img-gallery img {
width: 100%;
height: 100%;
object-fit: cover;
transition:transform 0.5s;
}
.img-gallery a:hover img{
transform:scale(1.25);
}
<div class="img-gallery">
<div class="row">
<a href="#" title="Show large image"><span><img itemprop="image" src="https://farm7.staticflickr.com/6217/6216951796_e50778255c.jpg" id="img-1-3"></span></a>
<a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/d6/df/51/d6df512a2f15f517767b4d82d2d97a4c.jpg" id="img-1-4"></span></a>
<a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/ec/a9/dd/eca9dd106a04cdbee399870252ef711f.jpg" id="img-1-5"></span></a>
</div>
<div class="row">
<a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/7d/01/19/7d0119a2fec989e208f288326c7cad0f.jpg" id="img-1-6"></span></a>
<a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/d8/c3/32/d8c332d09b03673845b2e92a48816233.jpg" id="img-1-7"></span></a>
<a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/88/3b/dd/883bddab14168f5f0807fec021002d8d.jpg" id="img-1-8"></span></a>
</div>
<div class="row">
<a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/8e/4f/bb/8e4fbb89b155d15521b80d1baf9290d1.jpg" id="img-1-9"></span></a>
</div>
</div>
Ответ 2
Это довольно просто: вы можете использовать padding-bottom: 100%
hack для форматирования 1:1. Согласно спецификации CSS, вертикальные поля /paddings, объявленные в процентах, ссылаются на родительскую ширину. Логика этого никогда не была четко объяснена, но я подозреваю, что это предотвращает круговые вычисления.
В любом случае, теперь вы знаете, что вы можете использовать padding-bottom: <percentage>
для принудительного фиксированного соотношения сторон;) теперь мы просто применяем это к .img-gallery span
. Не забудьте установить его высоту в 0, так как нам больше не нужно указывать высоту:
.img-gallery span {
height: 0;
display: block;
border-radius: 50%;
position: relative;
padding-bottom: 100%;
overflow: hidden;
transition: transform 250ms;
z-index: 2;
}
p/s: Я не очень уверен, почему вы устанавливаете дополнение на 0 в элементе :nth-child(2n)
при наведении, поэтому я удалил его сейчас.
Вот пример доказательства:
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.img-gallery {
background: #fafafa;
padding: 24px;
min-width: 320px;
width: 90%;
margin: 0 auto;
}
.img-gallery .row {
display: flex;
flex-wrap: nowrap;
justify-content: space-around;
align-items: center;
}
.img-gallery a {
display: block;
text-decoration: none;
background-image: linear-gradient(60deg, #004494 0%, #7db9e8 78%, #c2dfed 100%);
overflow: hidden;
border-radius: 50%;
padding: 3px;
flex: 1;
margin: 0 24px;
transition: padding 200ms;
}
.img-gallery .row:first-of-type a:not(:nth-child(2)) {
width: 30%;
width: calc((60% - 96px) / 2);
}
.img-gallery .row:first-of-type a:nth-child(2) {
flex: 2;
padding: 4px;
}
.img-gallery span {
height: 0;
display: block;
border-radius: 50%;
position: relative;
padding-bottom: 100%;
overflow: hidden;
transition: transform 250ms;
z-index: 2;
}
.img-gallery img {
width: 100%;
object-fit: cover;
transition: transform 250ms;
}
.img-gallery a:hover img {
transform: scale(1.25);
}
.img-gallery span::before {
content: "";
background-image: linear-gradient(60deg, transparent 48%, #ffc5e7 100%);
width: 100%;
height: 100%;
position: absolute;
z-index: 2;
border-radius: 50%;
opacity: .72;
}
<div class="img-gallery">
<div class="row">
<a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/b3/9c/54/b39c54776074d07ee0b567826768730a.jpg" id="img-1-3"></span></a>
<a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/d6/df/51/d6df512a2f15f517767b4d82d2d97a4c.jpg" id="img-1-4"></span></a>
<a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/ec/a9/dd/eca9dd106a04cdbee399870252ef711f.jpg" id="img-1-5"></span></a>
</div>
<div class="row">
<a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/7d/01/19/7d0119a2fec989e208f288326c7cad0f.jpg" id="img-1-6"></span></a>
<a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/d8/c3/32/d8c332d09b03673845b2e92a48816233.jpg" id="img-1-7"></span></a>
<a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/88/3b/dd/883bddab14168f5f0807fec021002d8d.jpg" id="img-1-8"></span></a>
</div>
<div class="row">
<a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/8e/4f/bb/8e4fbb89b155d15521b80d1baf9290d1.jpg" id="img-1-9"></span></a>
</div>
</div>
Ответ 3
Если вам нужно, чтобы они были идеальными квадратами, я думаю, что единственный способ - это заставить их размеры (ширина, высота). В противном случае вам понадобится Javascript.
И если вы беспокоитесь о мобильных чувствительных или разных размерах экрана, просто используйте @media
и исправьте ширину/высоту до ожидаемых размеров.
.img-gallery {
width: 90%;
}
.img-gallery .row {
display: flex;
align-items: center;
justify-content: center;
}
.img-gallery a {
display: block;
flex: 1;
}
.img-gallery span {
width: 150px;
height: 150px;
display: block;
border-radius: 50%;
position: relative;
margin: auto;
overflow: hidden;
}
.img-gallery a:nth-child(2) {
flex: 2;
text-align: center;
}
.img-gallery .row:first-of-type a:nth-child(2) span {
width: 300px;
height: 300px;
}
.img-gallery img {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 250ms;
}
.img-gallery a:hover img {
transform: scale(1.25);
}
<div class="img-gallery">
<div class="row">
<a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/b3/9c/54/b39c54776074d07ee0b567826768730a.jpg" id="img-1-3"></span></a>
<a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/d6/df/51/d6df512a2f15f517767b4d82d2d97a4c.jpg" id="img-1-4"></span></a>
<a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/ec/a9/dd/eca9dd106a04cdbee399870252ef711f.jpg" id="img-1-5"></span></a>
</div>
<div class="row">
<a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/7d/01/19/7d0119a2fec989e208f288326c7cad0f.jpg" id="img-1-6"></span></a>
<a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/d8/c3/32/d8c332d09b03673845b2e92a48816233.jpg" id="img-1-7"></span></a>
<a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/88/3b/dd/883bddab14168f5f0807fec021002d8d.jpg" id="img-1-8"></span></a>
</div>
<div class="row">
<a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/8e/4f/bb/8e4fbb89b155d15521b80d1baf9290d1.jpg" id="img-1-9"></span></a>
</div>
</div>