I’m trying to display an image within a 100px x 100px container. The image’s aspect ratio is not 1:1, so using background-image: cover on the container fills it without distortion.
To achieve a special effect, I divided the image into five 20px wide slices and displayed them in separate divs arranged with flex. Each div uses background-image to show a specific part of the image, with background-position adjusted accordingly.
However, when I set each slice’s background-size
to cover
, the result does not match the effect of simply using background-image: cover on the container. I’m wondering if there’s a way to make each slice work like background-image: cover, so the image displays the same way it does when using background-image: cover on the entire container.
Is there a way to make each slice use background-size: cover and achieve the same effect as using background-image: cover on the entire container?
* {
padding: 0px;
margin: 0px;
box-sizing: border-box;
}
.slice-container {
height: 100px;
width: 100px;
display: flex;
}
.slices {
height: 100px;
width: 20px;
background-repeat: no-repeat;
background-size: 100px 100px;
background-image: url("https://images.unsplash.com/photo-1602431039221-64c1be92ad52?w=500&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MjB8fGZha2V8ZW58MHx8MHx8fDA%3D");
/* Ideally, I want to use background-size: cover here but it does not match the effect */
/* background-size: cover; */
}
.slices-1 {
background-position: 0px;
}
.slices-2 {
background-position: -20px;
}
.slices-3 {
background-position: -40px;
}
.slices-4 {
background-position: -60px;
}
.slices-5 {
background-position: -80px;
}
.cover-container {
height: 100px;
width: 100px;
background-repeat: no-repeat;
background-size: cover;
background-image: url("https://images.unsplash.com/photo-1602431039221-64c1be92ad52?w=500&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MjB8fGZha2V8ZW58MHx8MHx8fDA%3D");
}
<!-- Displaying image slices -->
<div class="slice-container">
<div class="slices slices-1"></div>
<div class="slices slices-2"></div>
<div class="slices slices-3"></div>
<div class="slices slices-4"></div>
<div class="slices slices-5"></div>
</div>
<br />
<!-- Full container background -->
<div class="cover-container"></div>
2
Answers
You can imitate what
cover
does usingbackground-size: x y
with proper values.cover
basically Scales the image (while preserving its ratio) to the smallest possible size to fill the container (that is: both its height and width completely cover the container).You can use JavaScript to calculate the correct
x
andy
but let’s assume the image size is indeed 500 by 750. This means for a container of 100 by 100 we would need the image to be 100 by 150.This will work well for images where the height is greater than the width. But
background-position-x
would be trickier to calculate, yet possible, for images where the width is greater than height.You can use cover if you put the background on a pseudo before element rather than on the slice itself.
That way you can position the pseudo element, having given it 100px width and height and it will be positioned correctly in its ‘host’ slice.
The slices have to have overflow: hidden.
This way you don’t need to know anything about the size or aspect ratio of the background image, CSS does the positioning and sizing for you. No JS involved.
This snippet has given the flex a gap so you can see the individual slices more clearly.