DEV Community

loading...
Cover image for The Breakpoint CSS-JS "Hack" - do not define breakpoints in JS

The Breakpoint CSS-JS "Hack" - do not define breakpoints in JS

activenode profile image David Lorenz ・2 min read

This trick is a best practice trick. Knowing that this is a best practice I thought this is a common thing but apparently it is not as widespread as I thought it would be.

So let me share it with you.

Do not redefine your breakpoints in JavaScript/TypeScript

I am assuming you are using either native CSS or SASS for your development so let's use SASS for my code snippets now.

Assume your breakpoints are defined as follows:

mobile => max-width: 599.99px
tablet => min-width: 600px
Enter fullscreen mode Exit fullscreen mode

Now what some people do is redefining those values in JS. But you can simply read the current breakpoint directly from CSS. Also you can pass all breakpoints through CSS as Single Source of Truth for UI ♥️

The trick is to use the :before in combination with content :

@media screen and (max-width: 599.99px) {
  body::before {
   content: "mobile";
  }
}

@media screen and (min-width: 600px) {
  body::before {
   content: "tablet";
  }
}
Enter fullscreen mode Exit fullscreen mode

You can access this in JS via getComputedStyle(document.body, 'before').content and it would give you e.g. "mobile" or "tablet" here. So the only thing left to do is to remove the quotes like so:

const breakpoint = 
  getComputedStyle(
    document.body, 
    'before'
  )
  .content
  .replace(/"/g, '');
Enter fullscreen mode Exit fullscreen mode

Now if you want to have all definitions from CSS you could do something like this:

.media-queries::before {
  display: none;
  content: "mobile=(max-width: 599.99px);tablet=(min-width: 600px)";
}
Enter fullscreen mode Exit fullscreen mode

Now you can read that content and use actually matchMedia or whatever you want but the important part is to always have the Design in CSS and not duplicated in JS.

Here is an actual demo you can check out:
https://codesandbox.io/s/reading-media-queries-bps-from-css-06zjh?file=/index.html

Discussion (4)

Collapse
pankajpatel profile image
Pankaj Patel

This is really a neat trick. Thanks for sharing.

There is possible rink to expose these MQ texts to user.

Though I would only suggest this approach if you are not using any bundler for your project and delivering JS project.

I would suggest to keep breakpoints in JS file and provide the breakpoints' value to CSS with PostCSS or SCSS during the transpiling process.

Collapse
activenode profile image
David Lorenz Author

Actually, since CSS is the SSOT for UI/Design it is recommended architecturally to keep it in SCSS.

Using a bundler however you can also do it the other way round and import ... scss values within JS .

Collapse
pankajpatel profile image
Pankaj Patel

I agree with SSOT being in CSS

But getting values is readable format from CSS to JS is hacky and that's why making JS as SSOT for Breakpoints seems like a sane approach which doesn't involve custom solutions to maintain SSOT.

When creating Design Systems, there are more values which you might wanna share between CSS and JS contexts and for that reason JS seems to be a better place for such values.

I am not sure about the ease or possibility of importing values from scss via import, maybe you can point me to such resource 🧐

Thread Thread
activenode profile image
David Lorenz Author

Thanks for pointing that out. Sure thing I can try to make a super quick post about that ASAP :) will get back to you

Forem Open with the Forem app