Web Design


Sailboat race in Bellingham Bay

How to Create a Body Border Around a Page's Content

This post is written in the context of modern mobile first web design, where developers begin with a design for the smallest viewports, and change their CSS styles at certain breakpoints as the viewport increases. At the largest breakpoint, most web developers use a max width for an overall page because 1) they need to stop adjusting styles at some point and 2) a super wide site doesn't add to a viewer's experience, people expect to scroll to take comfortable "bites" of content. On small and medium viewports, the physical edge of a device (or the edge of a browser window) nicely frames the content. But when viewed on a large screen one may find with all that empty space, their design looks too barren, isolated, and lonely!

In this post I introduce the design element of framing your content with a customized CSS body border. There are many how-tos explaining how to add a whole page border, but their execution places the border around the far edge of the page, right next to the edge of the viewport. This solution can do that, but is a little sexier, looks better on all large viewports, and is fully customizable. Want to jump the example? Skip to the code.

An Example from Our Portfolio

screenshot of Erin Norman Gardens site without a frame in the design, it looks like it's swimming in too much empty space
Bellingham Gardener Erin Norman Garden's blog page without a frame.

The site looks a little empty as is. Most developers and many clients aim for a "clean" aesthetic and this style can certainly feel desolate on a wide screen. Creating a frame with the CSS border property helps make the overall design feel a little more complete, while still minimalist. Check out the difference with the frame.

screenshot of Erin Norman Gardens site with a frame in the design, it looks more enclosed like a physical page
Bellingham Gardener Erin Norman Garden's blog page with "body border" frame.

It's a simple and subtle addition, but I like how it looks a physical page. I also like how the space between the border and the content stays the same regardless of browser width. And with CSS it's very versatile. We'll review some of the ways you can make your frame more unique, but in this case, we made the border frame the same width, style, and color as the other lines in our design. It's vanilla, but it works.

Making Your Frame

I wrote a CodePen to explain the process. Check it out on CodePen to play with it and see better how the page responds to an increased viewport, or toggle the magnification from 1x to 0.5x or 0.25x in the embedded pen below.

See the Pen Framing a Page for Large Screens by Mac Bubb (@macbubb) on CodePen.

HTML for the Frame Design Element

css for example, follow link for codepen
See the CodePen if you want to cut and paste.

All of your content needs to be wrapped in a <div> tag. In my CodePen I used the class .outer-box-frame. You can add the class to your <body>, or put it inside a new <div> like my pen, but don't apply it in the <html> tag. You can end up with the same result if you do, by messing with the margin outside of the body border, but adding a margin style to the <html> tag just feels icky.

CSS for the Frame Design Element

css for example, follow link for CodePen
Is it overkill to load responsive sized screen shots of code?

Since I only want the frame to appear on large viewports, I used a media query set at 50 rem. Of course, use whatever breakpoint you wish, I usually stick with the standard breakpoints from my go-to CSS framework ZURB Foundation.

Within the media query we'll apply some styles to our wrapper. I used the shorthand border: 1rem solid #4B7355;. You can go nuts with it and really customize it to fit the overall design of your page.

Follow the CSS box model to get your spacing just right. I set margin: 5rem auto; to put 5rem of space at the top and bottom and setting left/right to auto centers the frame. I set padding: 5rem; to define the inner padding between the frame and the content within. Speaking of which, the content within already has it's own padding based on the layout I want on the smaller viewports, which I keep. The last thing we need to set is a max-width for the frame, otherwise it will fill all of the available space. We want the frame to be the same size as our media query breakpoint minus the widths of our padding and frame. So the arithmetic is breakpoint - 2(margin + padding) = 50 rem - 2(1 rem + 5 rem) = 38 rem.

In my example I also changed the background-color of the <body> to a green a snagged from the picture. To avoid the color style cascading into the <body> I set the <body>'s background-color to white.

Thanks for reading and have fun with it!