I am working on a WordPress theme and want to enable users to use full-width blocks in it. For this I am using the following HTML/CSS structure (reduced to the basic problem).
(note: although this is for a WordPress theme, the problem itself is not related to WordPress, but "only" a CSS problem, since I can even reproduce it with this very basic structure in a SO snippet)
* {
box-sizing: border-box;
}
html,
body {
margin: 0;
height: 100%;
}
.content {
width: 100%;
max-width: 400px;
margin: 0 auto;
overflow-y: visible;
background: #eee;
}
.alignfull {
margin-left: calc(50% - 50vw);
margin-right: calc(50% - 50vw);
background: #ccc;
}
<div class="content">
<p>Some regular text. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante,
dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui.</p>
<p class="alignfull">
Some more text - should be full width. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam
lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. </p>
<p>Some regular text again. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem
ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. </p>
</div>
So there is a .content
container with a max-width
pixel value, horizontally centered by using margin: 0 auto;
. In there, regular blocks (i.e. the first and last p
here) will have the default width: auto
, so they will be as wide as their parent .content
.
To create a full-width container, the .alignfull
class is applied (second p
in my example). The left and right margins for this are defined as calc(50% - 50vw);
, which (when the viewport is wider than the min-width of .content
) should create a negative margin value that is exactly the distance between the content container and the edge of the viewport. That way that element should have the exact width of the viewport.
But that doesn't work: the .alignfull
element ends up being wider than the viewport by a few pixels.
What I realized:
It has to do with the vertical scrollbar: If the whole content is less high than the viewport (i.e. if no vertical scrollbar is visible), the problem doesn't appear. So, when a scrollbar is present, 100% width of a full-width element is less than 100vw.
In the "official" Twentynineteen theme, this is solved in a completely different way which avoids the use of the vw
unit and uses percentage values for the max-width of the content area. But I've seen tutorials that describe the method I have tried to use...
Is there any way to make it work properly using a px
value for the content container's width/max-width, as I did?
Addition after first answer
I should add that I had already used another method with which I am also not happy. This defines a max-width
for all direct children of the content container and changes that to 100% for .alignfull
.
However, this brings some other problems along: Floated elements don't stay inside the content area, but are floated far left or right, and elements which by default have left/right margins (like blockquote
) loose their margin settings, which are overwritten by the more specific .content>*
selector's margin: 0 auto
which is needed for centering. (see example below).
I know that the WordPress block editor puts floated images into a non-floated block (which would then get the max-width and be centered), but I'd like to be able to use the same CSS also for post formats for which the block editor is deactivated (using "Disable Gutenberg") and where therefore images are not necessarily wrapped in non-floated blocks, i.e. where floated images (which are not in any container elements) would end up far right/left.
* {
box-sizing: border-box;
}
html,
body {
margin: 0;
height: 100%;
}
.content>* {
max-width: 400px;
margin: 0 auto;
background: #eee;
}
blockquote {
margin: 30px 40px;
background: #fc7;
color: red;
}
.floated_img {
float: right;
width: 20%;
height: auto;
}
.alignfull {
max-width: none;
background: #ccc;
}
<div class="content">
<p>Some regular text. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante,dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui.</p>
<img class="floated_img" src="http://lorempixel.com/output/food-h-c-117-198-7.jpg">
<p>Some regular text. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante,dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui.</p>
<p>Some regular text. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante,dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui.</p>
<p>Some regular text. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante,dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui.</p>
<p class="alignfull">
Some more text - should be full width. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam
lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. </p>
<blockquote>This should be a blockquote</blockquote>
<p>Some regular text again. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem
ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. </p>
</div>