Responsify
#Smooth out layout jumps at breakpoints
What is responsify?
#responsify verb to make an HTML element fluidly adapt to changes in viewport size
At my past job at a digital agency I transformed Photoshop, Sketch, and InVision designs into functioning websites. But the designs gave no instructions on how to handle the in-between resolutions. calc()
function to fluidly change width
, margin
, left
, etc. so they match the value at the neighboring breakpoint.
If you're still unclear what exactly it is and how it works, you're not alone. Many told me it didn't click for them until they saw it in action. So, below's a screen recording of an example.
Read on to learn how to use it in your project.
- Update:
- Today I learned that responsify is a rediscovery of CSS locks. Read the comparison between CSS locks and responsify.
Table of contents
#How to responsify
#Examples assume smallest viewport width of 320px, a tablet breakpoint at 768px, and a desktop breakpoint at 1024px.
Example 1 featuring two media queries
#Suppose a <div>
needs to be 90% wide below desktop breakpoint and 40% above that. Because you practice mobile-first approach, you start with:
div {
width: 90%;
}
and for desktop you add:
@media (min-width: 1024px) {
div {
width: 40%;
}
}
You want to gradually transition between these two values so you reserve, let's say, the 900px - 1024px range to smooth this out. You add another media query with the magic ๐ช calc()
value that you generate using the responsify form below and you're done! ๐
@media (min-width: 900px) and (max-width: 1023px) {
div {
width: calc(3716.129px - 322.903%); /* https://responsify.dev - parent lower bound: 900px; parent upper bound: 1024px; element lower bound: 90%; element upper bound: 40%; */
}
}
Note the comment that accompanies calc()
value. Preserving input values makes it easier to maintain the code.
The comment also includes https://responsify.dev
both as a reference for future maintainers and as a unique string you can match against when tracking down responsified values.
Without responsify:
With responsify:
You want the <body>
's padding
to increase from 10px to 50px, and have it stay at 50px once it hits the desktop breakpoint. For desktop and above you start off with:
body {
padding: 50px;
}
and for below desktop you add:
@media (max-width: 1023px) {
body {
padding: calc(-8.182px + 5.682vw); /* https://responsify.dev - viewport lower bound: 320px; viewport upper bound: 1024px; element lower bound: 10px; element upper bound: 50px; */
}
}
I'm not a fan of using a max-width
media query because it smells of a desktop-first approach ๐, but I've included it here for completeness' sake.
You want the <header>
's height
to increase from 40px to 90px, and have it stay at 90px once it hits the desktop breakpoint.
header {
height: calc(17.273px + 7.102vw); /* https://responsify.dev - viewport lower bound: 320px; viewport upper bound: 1024px; element lower bound: 40px; element upper bound: 90px; */
max-height: 90px;
}
Without the max-height
the <header>
would continue to grow in height with increase in viewport width. This approach removes the need for a media query ๐, but is limited to width
and height
as no other property has a corresponding max-width
and max-height
. ๐
You want the <button>
's border-width
to increase from 1ch to 2ch, and have it stay at 2ch once it hits the desktop breakpoint. In this example let's say that the average character width is 13.65px.
button {
border-width: min(calc(0.545ch + 1.939vw), 2ch); /* https://responsify.dev - viewport lower bound: 320px; viewport upper bound: 1024px; element lower bound: 1ch; element upper bound: 2ch; "ch" width in pixels: 13.65; */
}
By using min()
you can do away with media query and you're not limited to width
and height
like in Example 3. ๐ฏ
You want the <footer>
's margin-top
to be 20px below tablet breakpoint, 200px above desktop breakpoint, and increase from 2.6vw at tablet breakpoint (0.026 * 768px โ
20px) to 19.5vw at desktop breakpoint (0.195 * 1024px โ
200px).
footer {
margin-top: clamp(20px, calc(-515.482px + 69.87vw), 200px); /* https://responsify.dev - viewport lower bound: 768px; viewport upper bound: 1024px; element lower bound: 2.75vw; element upper bound: 19.53vw; */
}
Responsify + clamp()
is a powerful combination ๐ช that also allows you to do away with media queries and also allows you to mix and match units, something you can't do with responsify alone.
JavaScript failed to execute. ๐ต You won't be able to generate a calc()
value.
You might be able to resolve the issue by reloading the page. If that doesn't work, update your browser to the latest version and try again. If that doesn't work please email me at petar@responsify.dev.
Error stack is logged to the console.
Generate responsified calc()
value using the form below.
Bookmark the link next to the form heading above for direct access to this form.
You can use responsify as a Sass @function
. Download _responsify.scss
, unzip it, and import it to your root Sass file. Usage examples are included in the file.
The advantage of using the Sass @function
is that you don't need comments documenting input values. ๐
Note that at the moment, Sass @function
doesn't support ch
and rem
units. ๐
Browser support
#Browser support is very good. In spite of IE having known issues with calc()
I haven't encountered any. Two of the examples use clamp()
and min()
, which IE doesn't support. As far as "exotic" ๐ CSS values go: vw
is supported by all browsers and ch
is narrower on IE compared to other browsers, so just look out for that.
Comparison with CSS locks
#CSS locks originated as Molten leading. In the article that introduced the concept and in almost every example I came across CSS locks are used for controlling line-height
and font-size
, even though it works with many CSS properties.
CSS locks and responsify are based on fundamentally the same logic/math and as such share many similarities. They both:
- work with CSS properties that accept a
px
value, - don't work with properties that accept keyword value like
visibility
, - don't work with properties that accept a unitless value like
z-index
.
There are also a few differences, most notable are listed in the following table.
Criterion | CSS locks | Responsify |
---|---|---|
Sass | CSS locks Sass function | Responsify Sass function |
PostCSS | postcss-scale | No |
Web interface | No | Yes |
Since | 2016 | 2019 |
Related resources
#There's a similar tool that can generate non-linear calc()
value.
For more awesomeness, James Gilyead and Trys Mudford created "Utopia" design system where elements scale proportionally and fluidly. It's an unconventional approach that uses a whole lot of calc()
, CSS variables, rem
and vw
relative units, all tied together with what seems to me as undecipherable math. Fascinating stuff. ๐ง