cascading space

Background Clipping

Cascade, with the phone-style flashlight turned on (It's just a white screen)
Not that kinda Light, dingus

There's a little-used property in CSS called background-clip. There's many other properties that adjust how backgrounds look. These can let you do things like change the color, add images, resize them, move them around, etc. What background-clip focuses on is where the edges of the viewable background are trimmed.

In it's usual use cases, you give it CSS box model values like content-box or border-box, which cut off the background right where the edges of the content are and where the outside edges of the border are, respectively. For all the possible values, check a source like MDN.

The one I wanted to highlight here is a bit of an outlier compared to the other box model values. Setting background-clip: text will trim the viewable background all the way down to where the edges of the text letters are. As is, it will look like the thing doesn't have a background at all - but if you also set the text color to be transparent, then you can see "through" the text to the background behind!1

OOH LOOKIT!

p {
    background-image: url('background-image.jpg');
    background-clip: text;
    color: transparent;
}

Here's a bonus trick as well, while we're here. You can adjust that background with all the usual background-related properties - including keeping the image fixed to the viewport. Add one line and the image will appear to move behind the text as you scroll, giving an extra dimension to the window illusion!

HOW FANCY!

p {
    background-image: url('background-image.jpg');
    background-clip: text;
    background-attachment: fixed;
    color: transparent;
}

Compatibility and Accessibility

As always, think about accessibility as part of your designs. If you use this method, make sure to choose a combination of image, background color, and font/font size that will make sure it remains readable, and with enough color contrast. Automated tools are especially bad at figuring out color contrast when an image is involved, so some human double-checking will definitely be needed in cases like these. Choosing a nice think block font and whacking the size way up always helps as well.

Both background-clip and background-attachment are pretty well supported across the board. But in the spirit of not being too careful, we should put these sorts of less common CSS methods behind an @supports rule - this will make sure the browser actually understands the property, and at the same time keep the newer, funkier rules out of sight and out of mind for older browsers. If they don't know what @supports does, nothing in that block will run at all, letting you put together a functional fallback style.

p {
    color: #ddd;
}
@supports (background-clip: text) {
    p {
        background-image: url('background-image.jpg');
        background-clip: text;
        background-attachment: fixed;
        color: transparent;
    }
}

Lastly, I discovered that there's reports of a bug or two specific to Firefox that come into play once background-clip: text and background-attachment: fixed are both involved. While I don't officially recommend hacks, you can usually make sure that Firefox users get the fallback version instead of the busted one with some more @supports trickery:

p {
    color: #ddd;
}
@supports (background-clip: text) {
    p {
        background-image: url('background-image.jpg');
        background-clip: text;
        background-attachment: fixed;
        color: transparent;
    }
}
@supports (-moz-appearance: none) {
    p {
        background-attachment: revert;
    }
}

So, Firefox users, if you were confused about the "How fancy!" demo above being, in fact, equally as fancy as the first one, that would be why. It's set background-attachment back to what it was at first, so that it looks as good as it's currently capable of looking for you. Credit for this particular hack goes to laaposto on StackOverflow. To clarify what's going on, -moz- is a vendor prefix - a way for Firefox to try pushing new features without breaking anything CSS was normally doing. Theoretically, only Firefox recognizes properties that start with -moz-.2 Now that we're in an era where vendor prefixes aren't much of a thing anymore, there's something kinda nice about those old things still being useful, even in a ghost-form like this.

Footnotes and Credits

  1. Example photo by Nathan Queloz on Unsplash.

  2. Safari has a similar one with -webkit-. Internet Explorer and Opera had their own prefixes back in the day too.

#background #css #snippet #tutorial