Show HN: Smooth out breakpoint layout jumps with responsify

76
#

What is responsify

#

Responsify is the name of my technique for smoothing out breakpoint layout jumps. It uses the CSS calc() function to fluidly change width, margin, left, etc. so they match the neighboring breakpoint value. 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

#

  1. Smooth out breakpoint layout jumps with responsify
    1. What is responsify
    2. Table of contents
    3. How to use
      1. Example 1 featuring two media queries
      2. Example 2 featuring max-width media query
      3. Example 3 featuring max-height
      4. Example 4 featuring clamp()
      5. Example 5 featuring ch and min()
    4. Responsify form
    5. Sass @function
    6. Browser support
    7. Comparison with CSS locks
    8. Related resources
  2. Privacy policy
  3. Accessibility statement

How to use

#

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

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:

Example 2 featuring max-width media query

#

You want the ‘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.

Example 3 featuring max-height

#

You want the

‘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

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. 👎

Example 4 featuring clamp()

#

You want the

‘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 allows you to mix and match units, something you can’t do with responsify alone.

Example 5 featuring ch and min()

#

You want the ‘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. 💯

Responsify form

#

Generate responsified calc() value using the form below. Bookmark the link next to the form heading above for direct access to this form.

Sass @function

#

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.

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. 🧠

Privacy policy

#

There is none because no data is collected. No ads 📢, no analytics 📊, no tracking 🕵️, no telemetry 📡, no cookies 🍪, no bullshit 🐂💩.

Accessibility statement

#

I try hard to make my work accessible. ♿️ If something isn’t working for you please email me at a11y@responsify.dev.

Read More

Charlie Layers
WRITTEN BY

Charlie Layers

Fill your life with experiences so you always have a great story to tell