Occasionally, your designer will hand you designs where elements break the layout's horizontal container width, like navigation buttons of a slider that should be at the left/right of the browser window, or simply by applying a background color that reaches until the left and right of the browser window.
In the past, we've done some horrible things to achieve that. Like margin: 0 -10000px
plus overflow-x: hidden
.
There is a much saner approach.
Consider the following markup:
<body>
<div class="container">
<div class="section">
Hello
</div>
</div>
</div>
Let's say .container
encloses its contents like so:
.container {
margin: 0 auto;
max-width: 800px;
}
If you simply set the background color of .section
, it
looks odd
Show archive.org snapshot
.
.section {
background-color: #aaf;
}
You can use the ::before
and ::after
elements to fill in the blanks for you. CSS calc
will help you out:
.section {
background-color: #aaf;
position: relative;
}
.section::before,
.section::after {
background-color: #aaf;
content: '';
position: absolute;
top: 0;
bottom: 0;
}
.section::before {
left: calc(50% - 50vw);
right: 100%;
}
.section::after {
left: 100%;
right: calc(50% - 50vw);
}
Here is how we place the ::before
element left of the section element (and ::after
vice versa):
-
left: calc(50% - 50vw)
is the key:left: 50%
is the center of the element. We subtract half the viewport width and end up at the very left of the window. -
right: 100%
means that the right side of::before
ends at the left of.section
.
Using this approach, we do not need to know about the section height or container dimensions [1] and won't overlay any contents of the element itself, while actually expanding the element's interactable area [2].
View the attached example Show archive.org snapshot to see it in action.
Note that if you have a vertical scrollbar, 100vw will
include the scrollbar width
Show archive.org snapshot
, effectively causing a horizontal scrollbar. To cover clickable areas, it's often fine to use 99vw or 98vw and accept a small non-clickable margin. Or you could still use overflow-x: hidden
and feel a little bad about it.
[1] One might argue that could also omit position: relative
on .section
, and place the before/after helpers using left: 0
or right: 0
. However, you'd then need to know the height or start/end offset of the section itself.
For the "slider buttons" case, you'd need relative position on your element anyway (to vertically center them), so you're already halfway there.
[2] If you want to style a slider whose next/previous buttons live outside the slider and should appear only when hovering the entire "row" the slider is placed in, you should also use this. Otherwise buttons appear when hovering the (containered) slider, but disappear again when moving the mouse pointer to the left or right. Hovering the before/after elements actually means hovering the element itself.