I’ve laid pages out many different ways, but my favorite is using CSS grid along with a few other tricks. The example below is vanilla HTML/CSS; however, the concept can be adapted to any SPA framework.
Before going into the full example, I’ll point out a few interesting tidbits.
body {
min-height: 100vh;
margin: 0;
display: grid;
}
This ensures the body occupies the full screen height, allowing us to stick the page footer to the bottom if the content isn’t tall enough to push it offscreen. The vh
unit is “view height” and 100vh
means “100% of the view height.”
.app {
display: grid;
grid-template-rows:
[header-start]
min-content
[header-end content-start side-start]
1fr
[content-end side-end footer-start]
min-content
[footer-end];
grid-template-columns:
[header-start content-start footer-start]
auto
[content-end side-start]
300px
[side-end header-end footer-end];
}
The above sets up the page with a grid, naming each line of the grid (names fall nicely between the [ ]
brackets). In the full example, you will see how we restructure the grid through media queries. As long as all of our line names are present, the page will reflow seamlessly, offering a clean entry point into high-level, responsive design.
.header {
// ...
grid-row: header-start / header-end;
grid-column: header-start / header-end;
// ...
}
The above allows us to define what part of the grid the header should occupy using the named lines from the grid definition.
.header {
// ...
position: sticky;
top: 0;
// ...
}
The above approach allows the header to remain at the top of the page when scrolling. You can choose a different value for top to get it to stick to a different point. The benefit of position: sticky
over fixed or absolute is that it allows the header to continue to be a part of the layout of the grid. With something like position: fixed
you would need to add some top margin to the content to compensate for the height of the header. Less than ideal.
.content {
padding: 20px;
grid-row: content-start / content-end;
grid-column: content-start / content-end;
background: green;
display: grid;
grid-template-columns: repeat(auto-fill, 500px);
grid-template-rows: 300px;
grid-auto-columns: 500px;
grid-auto-rows: 300px;
grid-auto-flow: dense;
grid-row-gap: 20px;
grid-column-gap: 20px;
justify-content: center;
}
The above is simply a way to lay out the boxes to give the content the necessary height.
And, finally, the full example is here.
Phone
Wide Screen
Narrow Screen
Looking for more like this?
Sign up for our monthly newsletter to receive helpful articles, case studies, and stories from our team.
Quickly Prototyping a Ktor HTTP API
August 18, 2022Whether it’s needing a quick REST API for a personal project, or quickly prototyping a mockup for a client, I like to look for web server frameworks that help me get up and running with minimal configuration and are easy to use. I recently converted a personal project’s API from an Express web server to a Ktor web server and it felt like a breeze. I’ll share below an example of what I found and how easy it is to get a Ktor server up and running.
Read moreProduct Strategy
November 22, 2022A look at Product Strategy at MichiganLabs. Why we do it, what it is, what it is not, and how we approach it.
Read moreMake Your Website Shine Through Shareable Meta tags
June 20, 2023Improve the web site preview used by chat apps, websites, and social media with these easy tips.
Read more