If you insert images into a post or something similar, in most cases, they will have the maximum width of the text content. If the pictures are good, it can be cool to let them go beyond the width of the content area, for example from one border of the browser to the other in a one-column layout. This post shows you how to make this happen — as well in one-column as sidebar layout.
Update from March 18, 2017: Dave Rupert shows a more elegant way of full bleed elements in one-column layouts in hist post »Hassle-free Full Bleed with *:not()« which can be used instead of my proposed first solution. He uses the :not()
selector to exclude elements from a max width. That can look like that (code from Dave’s post):
.post > *:not( img ):not( video ) {
margin-left: auto;
margin-right: auto;
max-width: 50rem;
padding-left: 5%;
padding-right: 5%;
}
Images beyond the content area in one-column layouts
There are two possibilities for one-column layouts:
- You do not set a maximum width for the element which is wrapped around the content, but for every content element. For the images, you overwrite that value, so they are displayed wider.
- You set the width of the images with vw so that it can be displayed larger than the parent element.
Both solutions have advantages and disadvantages.
Maximum width directly for the content elements
The first solution’s CSS can look like that:
.entry-content > * {
margin-left: auto;
margin-right: auto;
max-width: 800px;
}
.entry-content > .size-full {
display: block;
max-width: 100%;
}
Code language: CSS (css)
The disadvantage of that:
- We have to set a maximum width for every direct child element of
.entry-content
via.entry-content > *
.
Advantages of that:
- No browser-specific problems like with
vw
. - The image will not be scaled up beyond its natural size. That can be the case when using
vw
.
You can see a live example of this solution on CodePen.
Width in vw
The solution with vw
can look like that:
.entry-content {
margin-left: auto;
margin-right: auto;
max-width: 800px;
}
.entry-content .size-full {
display: block;
left: 50%;
position: relative;
transform: translateX(-50%);
width: 100vw;
}
Code language: CSS (css)
Disadvantages of that:
- The image goes over the whole width of the viewport – no matter, if the viewport is 2,000 pixels wide and the image only 1,500 (I will explain how to prevent this shortly).
- We need to center the image — in this example done with the cooperation of
left
,position
andtransform
. - Browsers interpret
100vw
differently. Firefox stretches the image over the whole width of the viewport, including the scroll bar. Because of that, you will get an extra horizontal scroll bar, and a few pixels of the image are not visible. Other browsers implemented100vw
as the width of the viewport without the scroll bar. If you use this solution, you have to useoverflow-x: hidden;
on thehtml
element to hide the horizontal scroll bar.
The advantage of that:
- We do not need to set a maximum width with the star selector but only for the container of the content elements.
Set image width as maximum width when using vw
The significant disadvantage of using vw
is, in my opinion, that the image can be stretched beyond its natural size. For that, there is the following solution: We fetch the natural width from each image and set it as the max-width
via inline styles. We pass the width of 100vw
as inline styles too, so it only applies if adding the maximum width worked. Otherwise, the image will remain on the width of the content elements.
This is the solution:
{
let fullWidthImages = document.querySelectorAll('.entry-content .size-full');
if (fullWidthImages.length != 0) {
for (let fullWidthImage of fullWidthImages) {
let naturalWidth = fullWidthImage.naturalWidth;
fullWidthImage.style.maxWidth = naturalWidth + 'px';
fullWidthImage.style.width = '100vw';
}
}
}
Code language: JavaScript (javascript)
We query all elements with the specified class and loop through the list. We get the actual width of the image with .naturalWidth
and set this as the maximum width and 100vw
as width. This solves the problem with the maximum width, but the problem with the partly hidden image in Firefox remains. For a one-column layout, I would prefer the first solution.
There is also a pen for the one-column solution with vw
.
Images beyond the content area in sidebar layout
I am currently working on a theme which should let the user display images larger than the content area also in the sidebar layout. That can look like this:
Theoretically and with some calculation, we maybe could work here with the solution of setting a maximum width of the content elements, too. But I will only show a solution with vw
. The starting point is a default two-column layout, with a wrapper which specifies the maximum width of main content and sidebar.
We need the earlier explained JavaScript to set the maximum width of the images. Instead of using 100vw
for width
, you should use 100%
and specify this in the CSS file instead of inline. If the viewport becomes wider than the max width of the wrapper, you can set a breakpoint and specify a width for the images with calc()
, so they become larger than the content area. You should also set a float: right;
for the images, so they are getting larger on the left side. In the theme, the CSS looks like that:
@media screen and (min-width: 80em) {
.sidebar-template .large-featured-image-template .wp-post-image {
float: right;
width: calc(100% + ((100vw - 1200px - 2.8rem) / 4));
}
}
Code language: CSS (css)
The wrapper reached its max width of 1,200 pixels, and I set the width of the images to the width of the content container (100%
) and add roughly a quarter of the space, which remains on the left and right of the 1,200 pixels. So the image uses around half of the area, which is empty on the left beside the content.