Viewport
If you’re writing your website from scratch, the very first thing you need to do in order for your website to be responsive is to add the viewport meta tag between your <head></head>
tags, recommended at the very top:
<meta name="viewport" content="width=device-width, initial-scale=1.0">
Why do I need to add this meta tag? What does it do? Before mobile devices, browsers displayed a specific area, otherwise known as the viewport, due to the limited variety of screen resolutions. When mobile and tablet were introduced, browser’s were never updated to compensate for the dramatic change of screen resolution, therefore setting the viewport manually is now the current normal when creating a responsive design (read more).
Media Queries
The key to creating a responsive design is to utilize media queries which allow you to alter CSS depending on browser width. By using the @media rule at the very bottom of your style sheet, you can specify either the minimum width or maximum width of a specific resolution that will also override any previous CSS that does not have the !important property. Each media query is called a breakpoint as you will be able to physically see the CSS “break” and change when expanding or shrinking your browser at the specific resolutions you’ve set. While there is no limit to how many breakpoints you can set, below is a standard set up:
/* --- MOBILE (base) --- */
.content {
padding: 10px 20px;
font-size: 12px;
}
/* --- TABLET (will override the mobile base on browser widths 768px and wider) --- */
@media only screen and (min-width: 768px) {
.content {
padding: 20px 30px;
font-size: 13px;
}
}
/* --- DESKTOP (will override the tablet and mobile base on browser widths 992px and wider) --- */
@media only screen and (min-width: 992px) {
.content {
padding: 40px 50px;
}
}
The only properties that are shown above are padding
and font-size
. The padding
is increased along with the resolution and the font-size
is increased by one pixel which while are still important aspects especially on smaller devices, there is so much more that goes into making a design responsive. Experiment with this CodePen that has a basic layout, fixed navigation bar and two columns of content so you can see how media queries can be used to accomplish a responsive design.
Why is mobile listed as the base CSS? It is recommended to code the mobile display of your website first since it is more common for users to use their mobile device(s) over their desktop to browse the internet and coding the mobile layout first will ensure it’s loaded as quickly as possible.
Resolutions
Not every mobile and tablet has the same screen resolution just like all desktops vary, so how do you know what sizes to adjust your designs for? It’s best to always use percentages for widths and/or a minimum/maximum widths instead of fixed widths. You will limit content running off the screen on smaller resolutions this way, however, specifying CSS for different screen resolutions using media queries will eliminate any left over issues:
- Mobile
320px – 768px - Tablet
768px – 992px - Desktop
992px +
Are these sizes standard? While the listed resolutions are standard, they can vary because new devices are being made every year with different screen resolutions. These resolutions also change when mobiles are switched from portrait to landscape and should be noted when designing. It’s best to also research the most up to date common media query breakpoints when designing a responsive website (read more).
Flexbox
The best way, in my personal opinion, to write CSS for a responsive design is to utilize the layout module flexbox. In order to use flexbox, you have to change the browser’s default display of block
to flex
within each container you wish to use its properties. Flexbox has container properties that are set to the container and effect all of it’s immediate contents and child element properties that are set to specific elements.
What’s the best way to learn flexbox? I learned flexbox by playing Flexbox Froggy which is an adorable game- but because it’s interactive it’s far easier to grasp and remember each property and what they can accomplish.
- Direction
flex-direction
controls the direction in which the elements within the flex container are listed and it’s arecolumn
,column-reverse
,row
, androw-reverse
. - Wrap
flex-wrap
has the default value ofnowrap
with the option to allow the elements within the flex container towrap
as well as to reverse it withwrap-reverse
. - Flow
flex-flow
is the shorthand offlex-direction
andflex-wrap
, giving you the ability to set both with a single property. - X Alignment
justify-content
aligns the container’s elements horizontally using the valuesflex-start
,center
,flex-end
,space-between
,space-around
,space-evenly
, andstretch
. - Y Alignment
align-items
aligns the container’s elements vertically using the valuesflex-start
,center
,flex-end
,space-between
,space-around
,space-evenly
, andstretch
. - Content Alignment
align-content
is only relative whenflex-wrap
is set towrap
as it controls the alignment of wrapping content.
The following example shows the default display positioning of <div>
containers. While each container has a background-color
, color
, font-size
, width
, and height
set- all other alignments you see are based on the default values of the browser. How would you align the boxes besides each other as well as centering their numbers vertically and horizontally based on your current knowledge? Instead of using inline-block
or float
to align each container besides the other and padding
, text-align
, or line-height
to center each number, we can use flexbox to accomplish our desired layout easily as well as change the direction, alignment, and spacing of the boxes themselves with only a few properties. Experiment using these flexbox container properties yourself by following my interactive tutorial on CodePen.
<div class="container">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
</div>
body { margin: 0; } /* i added this just to remove the default margin to the body the browser adds */
.container {
width: 100%;
min-height: 100vh; /* vh stands for viewport height! setting the height at 100vh tells the browser to display that container at 100% of the browser's viewport height at all times! this means that even if you shrink the height of the browser, the container will shrink along with it. using min-height instead allows the container to expand past the browser's height to accompany the content within the container without overflowing */
padding: 50px;
box-sizing: border-box; /* this ensures that the container's dimensions will not be altered by padding or borders */
}
/* this is the styling i gave the boxes */
.container > div {
width: 50px;
height: 50px;
margin: 10px;
background-color: #b8ceae;
color: white;
font-size: 20px;
}
/* LET'S EXPERIMENT!
go down the line following the directions in the comments to see how flexbox container properties effects the four boxes */
.container {
display: block;
/* change "block" to "flex". the default alignment of a flex container will align all the boxes side by side */
flex-direction: none;
/* change "none" to column", "column-reverse", "row", and "row-reverse" to change the boxes direction */
justify-content: center;
/* change "center" to "flex-start", "flex-end", "space-between", "space-around", "space-evenly" and "stretch" to change the alignment of the boxes horizontally. "stretch" only affects the boxes if they do not have a fixed width. "stetch" will also not stretch the objects past their maximum width if set */
align-items: center;
/* change "center" to "flex-start", "flex-end", "space-between", "space-around", "space-evenly" and "stretch" to change the alignment of the boxes vertically. "stretch" only affects the boxes if they do not have a fixed height. "stetch" will also not stretch the objects past their maximum height if set */
flex-wrap: nowrap;
/* put the boxes into rows then shrink the browser until the boxes begin to become squished. notice they boxes stay in their same line and will just adjust with size to fit. change "nowrap" to "wrap", and then "wrap-reverse" */
flex-flow: none;
/* this is the shorthand for flex-direction and flex-wrap to be able to set them both with a single property. change "none" to "row wrap", "row-reverse nowrap", etc. and notice that it will override the flex-direction and flex-wrap set before it as CSS loads top to bottom */
align-content: center;
/* with the boxes still set to wrap, change "center" to "flex-start", "flex-end", "space-between", "space-around", "space-evenly", or "stretch". this property only is relative to elements that are wrapping as it controls the alignment between each row or column, depending on the direction, that is wrapped */
}
.container > div {
display: block;
/* change "block" to "flex" to enable the below properties to center the numbers horizontally and vertically */
justify-content: center;
align-items: center;
}
Is flexbox the only responsive option? There are libraries like Bootstrap that support responsive layouts as well as other techniques like CSS Grid that can be used along with media queries. However, I primarily utilize flexbox throughout my responsive designs as it’s the most straight forward method in my opinion.
- Order
order
is used to re-order elements using a numerical value, the default being0
so the order within the HTML will not be overrode. - Grow
flex-grow
uses numerical values with the default0
to specify elements that can expand past their set dimensions on larger resolutions. - Shrink
flex-shrink
also uses numerical values with the default1
to specify elements that can shrink past their set dimensions on smaller resolutions. - Basis
flex-basis
is similar to setting amin-width
to an element as it uses pixel values, however it overrides set dimensions. - Flex
flex
is the shorthand offlex-grow
,flex-shrink
, andflex-basis
to allow you to set all three with a single property.
Using the same four boxes as before but at all different heights, this example has flexbox already enabled along with justify-content
, and align-items
to not only center the boxes but also their numbers. Follow this interactive CodePen tutorial to learn hands on how to utilize flexbox’s element properties to alter the size, positioning, and responsiveness of each box.
<div class="container">
<div class="one">1</div>
<div class="two">2</div>
<div class="three">3</div>
<div class="four">4</div>
</div>
<style>
body { margin: 0; } /* i added this just to remove the default margin to the body the browser adds */
.container {
width: 100%;
min-height: 100vh; /* vh stands for viewport height! setting the height at 100vh tells the browser to display that container at 100% of the browser's viewport height at all times! this means that even if you shrink the height of the browser, the container will shrink along with it. using min-height instead allows the container to expand past the browser's height to accompany the content within the container without overflowing */
padding: 50px;
box-sizing: border-box; /* this ensures that the container's dimensions will not be altered by padding or borders */
}
/* this is the styling i gave the boxes */
.container > div {
width: 50px;
margin: 10px;
background-color: #808080;
color: white;
font-size: 20px;
}
.one {
height: 70px;
}
.two {
height: 100px;
}
.three {
height: 150px;
}
.four {
height: 50px;
}
/* LET'S EXPERIMENT!
go down the line following the directions in the comments to see how flexbox element properties effects the four boxes */
.container {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
flex-wrap: wrap;
align-content: center;
}
.container > div {
display: flex;
justify-content: center;
align-items: center;
}
.one {
order: inherit;
/* change "inherit" to "4". move it after the 4th box. give the other boxes their own order numbers to change the entire order */
flex-grow: 0;
/* change "0" to "2", as the default value is "0". setting it to "1" tells the 1st box to expand to it's full ability */
}
.two {
flex-grow: 0;
/* set this box's grow to "1" and you'll see that it will grow just like the 1st box but will be smaller than it as you set a lower grow point. give this box a maximum width and note it will not grow past it */
}
.three {
flex-shrink: 1;
/* the default value of this property is "1" which allows the boxes to shrink when the browser gets smaller their their width. change "1" to "0" which tells the 3rd box not to shrink */
flex-basis: auto;
/* this is the equivilent of setting a min-width with the only difference that it overrides set dimensions. change "auto" to "200px" to make the 3rd box a minimum of 200 pixels wide */
}
.four {
flex: 0 0 auto;
/* change "auto" to "100px". this is short hand for flex-grow, flex-shrink, and flex-basis so you can set all three with just one property, you just set the 4th box's basis to 100 pixels */
align-self: center;
/* change "center" to "flex-start". the 4th box shifts to align to the top while the other boxes remain centered. this property acts just like align-items but is specific to a single element */
}
</style>
What is flexbox capable of? Among responsive designs you can also easily create fluid grids using just CSS (read more).
Media
All aspects of your design have to adjust depending on the resolution it’s being viewed on, including all images and videos to avoid overlapping and/or warping. You can set your default img
and video
elements to be responsive by just adding a 100% width
and an auto height
. With designs that call for content to sit over an image, like a banner, it’s advised to use compressed large resolution images as the background-image
with the CSS property background-size: cover;
to ensure that it will adjust accordingly with the browser. Experiment with these basic principles on this CodePen.
<div class="banner">
<a href="#">
<img src="https://designsbytrinityblair.com/wp-content/uploads/SPlscWHfkkuFJ0dMjSqo.webp" width="500px">
</a>
</div>
<style>
body { margin: 0; }
img, video {
width: 100%; /* the width property tells the image to be as big as it's container will let it despite it's actual dimensions, however, if you use max-width it will not expand beyond its set width */
height: auto;
}
.banner {
width: 100vw;
height: 100vh; /* vh stands for viewport height! setting the height at 100vh tells the browser to display that container at 100% of the browser's viewport height at all times! this means that even if you shrink the height of the browser, the container will shrink along with it. using min-height instead allows the container to expand past the browser's height to accompany the content within the container without overflowing */
background-image: url(https://designsbytrinityblair.com/wp-content/uploads/Ao0CjlefmNldQdxgPjKb.webp);
background-size: cover; /* for responsive designs i always use "cover" as "contain" and "100%" almost always cut off on some screen resolutions */
background-position: center center;
/* change the position from "center center" to "top left" or "bottom right" and see how the background image changes position */
/* this is just styling and alignment for the banner and logo */
box-shadow: inset 0 0 0 9999px rgba(68, 68, 68, 0.5);
display: flex;
justify-content: center;
align-items: center;
padding: 25%;
box-sizing: border-box;
}
</style>
How can I compress my images? You can compress images up to 5MB for free on TinyPNG. Compressing your images to ensure they are the smallest size possible ensures faster loading speeds, especially for large images.
Limitations
There are a few limitations when it comes to responsive design. Since you are designing for mobile devices as well as desktop, you have to remember that there are many functions that do not work on mobile.
- Tables
Because the format was created before mobile devices, tables will never be responsive. However, you can create responsive tables using flexbox (read more). - Hovers
Anything that requires the movement of a cursor will not work on mobile devices as they do not have a constant cursor and depend on touch for interactions. However, there is the beginnings of a solution that has yet to be perfected (read more).