Visually I can appreciate the difference, but in which situations should I prefer one over the other? Is there any point using them at all or can they be replaced by percentages?
Currently I don't seem to be able to go beyond a trial-error approach when using these properties, which does my head in.
Also I can only find pretty vague explanations and especially I find the W3C doc quite baffling.
Values have the following meanings:
‘contain’
Scale the image, while preserving its intrinsic aspect ratio (if any), to the largest size such that both its width and its height can fit inside the background positioning area.
‘cover’
Scale the image, while preserving its intrinsic aspect ratio (if any), to the smallest size such that both its width and its height can completely cover the background positioning area.
I'm probably being a bit thick, but can anyone give me a plain English explanation with relative examples?
Please use this fiddle. Thanks.
CSS
body{
width:500px;
height:500px;
background:url(http://upload.wikimedia.org/wikipedia/commons/1/1a/Bachalpseeflowers.jpg);
background-size:contain;
background-repeat:no-repeat;
}
Note
The accepted answer is the one I currently find the most concise and complete. Thanks everybody for their help.
background-size: contain; The keyword contain will resize the background image to make sure it remains fully visible. background-size: cover; The keyword cover will resize the background image to make sure the element is fully covered.
The background-size CSS property is used to set the size of a background image of an element. The background image can be stretched or constrained to fit into the existing space. It allows us to control the scaling of the background image.
The best website background image size is 1920 x 1080 pixels, according to Malama Online Marketing, and the ideal ratio is 16:9.
When we set background-size: 113% , it means the the width can be max 113% of the container's width, which would be, 63.28px and this is roughly 50% of the original image's width.
You can consider looking at the pseudocodes that govern the output. The values allotted to the image's size depend directly on the aspect ratios of container wrt aspect ratio of the background image.
Note: Aspect ratio = width / height
if (aspect ratio of container > aspect ratio of image)
image-height = container-height
image-width = aspect-ratio-preserved width
else
image-width = container width
image-height = aspect-ratio-preserved height
if (aspect ratio of container > aspect ratio of image)
image-width = container width
image-height = aspect-ratio-preserved height
else
image-height = container height
image-width = aspect-ratio-preserved width
You see the relation? In both cover
and contain
, aspect ratio is preserved. But the if - else conditions reverse in both the cases.
This is what makes cover
to cover full page, without any white portion visible. When aspect ratio of container is greater, scaling image so that its width becomes equal to container width. Now, height will be greater, as aspect ratio is smaller. Thus it covers the whole page without any white portion.
Q. Can they be replaced by percentages?
No, not simply by percentages. You'll need conditioning.
Q. In which situations should I prefer one over the other?
When you are creating a website, you wouldn't want any white portion in the fixed background. So use cover
.
contain
on the other can be used when you are using a repeating background (e.g. when you have a pattern image with very high aspect ratio wrt veiwport/container you can use contain
and set background-repeat
to repeat-y
). But a more appropriate use for contain
would be for a fixed height/width element.
Although the question assumes the reader already understands how the contain
and cover
values for background-size
work, here's a plain-English paraphrasing of what the spec says, which can serve as a quick primer:
background-size: contain
ensures that the entire background image will fit the background area, keeping its original aspect ratio. If the background area is smaller than the image, the image will shrink so that it can fit the background area. If the background area is either taller or wider than the image, then any parts of the area not occupied by the main image will either be filled by repetitions of the image, or letterboxes/whitespace if background-repeat
is set to no-repeat
.
background-size: cover
makes the background image as large as possible such that it will fill the entire background area leaving no gaps. The difference between cover
and 100% 100%
is that the aspect ratio of the image is preserved, so no unnatural stretching of the image occurs.
Note that neither of these two keyword values can be expressed using any combination of lengths, percentages, or auto
keywords.
So when do you use one over the other? Personally, I think cover
has more practical uses than contain
, so I will go with that first.1
One common use case of background-size: cover
is in a full-screen layout where the background image is rich in detail, such as a photo, and you want to feature this image prominently, albeit as a background as opposed to the main content.
You want just enough of the image to be able to completely cover the browser viewport or screen, regardless of the aspect ratio of the viewport, or whether the image or the viewport is in portrait or landscape. You're not concerned if any parts of the image are cropped out as a result of this, as long as the image fills up the entire background area and maintains its original aspect ratio.
Here's an example of a layout where the content is housed in a semitransparent white background, which hovers over a full-screen background. When you increase the height of the preview pane, notice that the image automatically scales up to ensure that it still covers the entire preview area.
html {
height: 100%;
background-image: url(http://upload.wikimedia.org/wikipedia/commons/1/1a/Bachalpseeflowers.jpg);
background-position: center center;
background-size: cover;
background-repeat: no-repeat;
background-attachment: fixed;
}
body {
width: 80%;
min-height: 100%;
background-color: rgba(255, 255, 255, 0.5);
margin: 5em auto;
padding: 1em;
}
If you use background-size: contain
instead, what happens is that the background image shrinks in order for the entire image to fit in the preview pane. This leaves ugly white letterboxes around the image depending on the aspect ratio of the preview pane, which ruins the effect.
So why would one use background-size: contain
if it leaves ugly blank spaces around the image? One use case that immediately comes to mind is if the designer doesn't care about the blank spaces, so long as the entire image fits within the background area.
That may sound contrived, but consider that not every image looks bad with empty space around it. This is where the example of using a logo instead of a photo actually demonstrates this best, even though you probably won't find yourself using a logo as a background image.
A logo is typically an irregular shape sitting on either a blank or completely transparent background. This leaves a canvas that can be filled by a solid color or a different background. Using background-size: contain
will ensure that the entire image fits the background without any parts of it being cropped out, but the image still looks right at home on the canvas.
But it doesn't necessarily have to apply to an irregularly-shaped image. It can apply to rectangular images as well. As long as you require that no cropping of the background image occurs, whitespace can either be seen as a reasonable tradeoff, or not a big deal at all. Remember fixed-width layouts? Think of background-size: contain
as essentially that, but for background images and in both portrait and landscape orientations: if you can ensure that the content will always fit the boundaries of the background image at all times, then whitespace becomes a non-issue altogether.
Although background-size: contain
will work whether or not the image is set to repeat, I can't think of any good use cases involving repeating backgrounds.
1Note that if you're using a gradient as a background, both contain
and cover
have no effect because gradients do not have any intrinsic dimensions. In both cases, the gradient will stretch to cover the container, as though you had specified 100% 100%
.
background-size:cover
will cover the entire div with the image. This could be useful for showing thumbnail images of a main image where the entire image being displayed isn't that important, but you still want to conform to a size for all images. (for example, a blog post excerpt)
background-size:contain
will show the entire image within the div. This can be useful if you specifically want to display the entirety of the images, but within a set container div size. (For example, a collection of company logos)
Both keep the image at the same aspect ratio
http://cdn.onextrapixel.com/wp-content/uploads/2012/02/cover-contain.jpg
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With