Add Beautiful Free Space around Images

On smaller devices, I want beautiful free space to surround the stunning image. The free space is the key to make the page look awesome.

To add some free space to surround the image, I add the following code for the <div> element.

div {
width: 100%;
padding: 3.5%;
}

Oops, the image moves to the right a little bit. A small part of the image goes beyond the <div> boundary and become invisible.

To find the reason, I open the Developer tools (I use Chrome) to see the exact size of the image. The page is loaded on an emulated iPhone X.

The page view in iPhone X
The size of the image

The width of the image is as wide as the screen size. This does not explain the why the image goes beyond the boundary.

Then I check the parent container (i.e., the <div>) of the image.

The size of the <div> element

The width of the <div> content box is 375px which equals to the screen size (because the <div> width is set to 100%), and equals to the image width (because the image width is set to 100%). The height is 5pxlarger than the image (why? I don't understand). However, the actual width of the <div> element is padding X 2 + width of content boxwhich adds up to 401.25px. The actual width of the <div> element is larger than the screen size. That is why the image goes beyond the border.

So I try a workaround. To fully display the image in the <div>, I change the image width to 93% (why 93%?, please read the box model again).This workaround does works!!

But wait, what if I have many images of different sizes and aspect ratios? I have to do the manual calculation many times. Furthermore, when I want to change the padding, I have to do manual calculation much more times. I don’t want this workaround. I like to instruct browsers to do this chore for me.

The problem comes from I don’t properly use CSS box model, because, by default, the box-sizing property is set to content-box. The width of an element is just the width of its content box. Padding and borders are not included.

I think about this problem for a while. Since the problem comes from the box model, I can find the cure in box model. Bingo, I know a CSS property box-sizing, and never used this before. When setting box-sizing to border-box, an element padding and border are included in the element’s total width and height. Then I add the following code to the very beginning of the style sheet.

* {
box-sizing: border-box;
}

Magic happens. The <div> and image behave as I expect. Padding surrounds the image properly, and adds some beautiful free space for readers to breath.

Image stays in the place as I expect
Size of the <div> element

I try to figure out certain rules from above experiments. For convenience, the code is listed below.

// HTML
<body>
<div>
<img src="/blog.jpg">
</div>
</body>
// CSS
div {
width: 100%;
padding: 3.5%;
}
div img {
width: 100%;
height: auto;
}

To translate the CSS code into plain English. I want the <div> to be as wide as the screen width. Then adds some free space around the image. The width of the free space and the image adds up to the screen width. The image keeps it aspect ratio.

The <div> element is the only child of the <body> element, and the <img> is the only child of the <div>.

By default, when box-sizing property is not set, content-box is used (keep this in mind).

The CSS code instruct the <div> to take up all width of <body> element. And the <img> takes up all width of the <div> element.

Now I must consider what are the width of <body> and the width of the <div>after the padding is added?

From the above experiment, the child element sits in the content box of the parent element. When setting a child element width to 100%, the child element takes up all width of the content box of the parent element.

When padding is added to the parent element, two things happen. One is that the total width of the parent element changes, and the other is that the width of the content box of the parent element does not change. Then this causes unwanted result.

Now set box-sizing to border-box.

// HTML
<body>
<div>
<img src="/blog.jpg">
</div>
</body>
// CSS
* {
box-sizing: border-box;
}
div {
width: 100%;
padding: 3.5%;
}
div img {
width: 100%;
height: auto;
}

When I sett a child element width to 100%, the child element still takes up all width of the content box of the parent element. However, when padding is added to the parent element, the total width of the parent element does not change, but the content box of the parent element gets smaller (compared to the one with box-sizing set to the default value).

There is huge difference between border-box and content-box. I will use boxrder-box, probably always.

If you want, you can move the padding: 3.5% to the <body> or the <img> element. Check the result. I believe you will understand better about border-box as I did.