I had someone write to me the other day that they were trying to visualize the different parts of the box model. They said they would just code up an example themselves, but there is no way to, say, set a background color for just the “padding” area of an element.
What they were talking about is something like this, the box model diagram available in DevTools:

I said, I think you… can! actually!
The trick lays in using the background-clip property in CSS, which allows you to stop the background-image property at different points in the box model. Here’s a really basic example of doing that, using the same colors as the model above:
The only one I’m “faking” there is the very outer shape (margin), which is drawn with an outline. It does match the value of margin though so it’s basically real!
I was a bit inspired to keep going, making all the values dynamic, so I made this, which labels the section as well.
I put a grid of content around it so that you could see the element push others away like the real box model does.
Is this actually useful ever? Sometimes!
Just the other day Wes Bos posted a really nice button effect and then re-created in HTML and CSS:
There is no real big problem with how Wes did it there, but he did use an extra element as well as pseudo elements to get it done. Here’s his demo.
Ana Tudor chimed in that it could be done without using any extra elements, and guess how? Background clipping!
I took a crack at that, and aside from a bit of an awkward need to set the background-size, I think I got it working:
This may actually be truly useful sometimes. For example, a CMS that is happy to spit out a <button> element but doesn’t offer inner HTML control of it. If you don’t need that anyway and can pull of the effect in CSS entirely, you’re in business.
Because I’m a glutton for punishment sometimes, I also decided to have a crack at it using border-image as well, which despite being the lest scrutable CSS property of all time, seems at least conceptually like the correct thing to use. I was able to get it working!
But for whatever reason border-image is incompatible with border-radius, so, whatever, that sucks.
I made a video explaining three more way to create such an effect and how to decide which way is the right one for your situation: https://www.youtube.com/watch?v=SRdZj0KfZ5s
“I took a crack at that, and aside from a bit of an awkward need to set the background-size”
You don’t need to set
background-size(norbackground-positionfor that matter), you need to setbackground-origintoborder-box. That’s what I meant with “make theconic-gradient()relative toborder-box” and that’s why theborder-boxafter theconic-gradient()in my example code.Generally, “relative to” =
background-origin, “restricted to” =background-clip.Gradients are sized and positioned relative to the
background-origin. By default, this is set topadding-box, so if there’s aborderthe gradient stretches from the top left corner of thepadding-boxacross the entirepadding-box. Then, since backgrounds are repeating by default, it repeats outside thepadding-boxin the border area.But if we change the
background-origintoborder-box, then the gradient stretches across theborder-boxfrom its top left corner.Both
background-originandbackground-clipcan be set in the shorthand. If we have two box values in the shorthand, the first applies tobackground-originand the second tobackground-clip. If we have a single box value in the shorthand, it applies to both.The first gradient is the cover and we want to set its
background-cliptopadding-box, not just itsbackground-origin(which is alreadypadding-boxby default). So a singlepadding-boxvalue after it does it – it sets thebackground-originto its default andbackground-clipto the value we want in this case.The second gradient is the one we want to see in the border area and we want it sized relative to the
border-box. So we want to set itsbackground-origintoborder-box, not just itsbackground-clip(which is alreadyborder-box) by default. So a singleborder-boxvalue after theconic-gradient()does it – it setsbackground-originto the value we want in this case andbackground-clipto its default.Basically, the code is just:
As for seeing the box model, I made a demo showing it in 3D too and how the roundings for the inner boxes are computed (
border-radiusapplies to theborder-box) https://codepen.io/thebabydino/pen/ZNeRbZ