Three Ways to Create Media Queries in JSS

JSS provides the underlying styling syntax and functionality in many UI libraries. For example, React Material-UI’s styling and theme system is directly built on the syntax seen in JSS.

In these examples of different ways to write media queries in JSS, I will use react-jss. This library is provided by the JSS team and integrates JSS into the React hooks API.

Media queries are commonly used to implement styling based on screen size. Other factors that can be detected and dynamically reacted to (pun intended!) are screen orientation and resolution.

My examples below don’t focus on types of media queries. Instead, I am investigating different possible syntax for implementing media queries. I will give examples of the three options listed in the Table of Contents.

We’ll create a solution for vertical stacking on screens wider than 720px and horizontal layout on smaller screens.

JSS Media Query Example
JSS Media Query Example

I’ll discuss why the third option isn’t on the same line as the first two later in the post.

A link to the Code Sandbox with full React code is in the Resources section.

Pure Media Query In JSS With @media

Most people who use media queries likely want a static value like the below example:

title1: {
  color: ({ theme }) => theme.color,
  "@media (min-width: 720px)": {
    display: "inline",
    paddingRight: "1%",
    width: "24%"
  }
}

This method doesn’t need any variables. CSS interprets the media query as an ‘if’ statement and only applies the conditional layout if the screen is greater than 720px.

The first of the three elements pictured above has the title1 class applied to it.

Media Query From Prop Value

If you want to calculate a dynamic breakpoint value and pass it in to the styles hook, here’s what the code looks like:

//In createUseStyles
title2: {
  color: ({ theme }) => theme.color,
  display: ({breakTripped}) => breakTripped ? 'inline' : 'block',
  width: ({breakTripped}) => breakTripped ? '24%' : '100%',
  paddingRight: ({breakTripped}) => breakTripped ? '1%' : '0%'
}

//In the component
const breakTripped = useWindowSize().width > 720;
const classes = useStyles({ theme, breakTripped });

In this code I pass in both theme and a breakTripped value. The breakTripped value is simply a boolean calculated in the component.

In my opinion, this is more verbose than it needs to be. However, I tried several other methods, such as the breakpoints methods used in Material-UI, but they were not considered valid syntax here.

Media Query From JSS Theme

I have to admit up front, I actually did not get this syntax to succeed. However, I’ll show you what I tried and why I expected it to work fine.

title3: {
  color: ({ theme }) => theme.color,
  [`@media (min-width: ${({ theme }) => {
    return theme.breakpoint;
  }}px)`]: {
    display: "inline",
    paddingRight: "1%",
    width: "24%"
  }
}

In this method I attempted to use the passed theme object in a string interpolation statement.

The error was that theme ‘was being used before it was declared’. Strangely, I could use theme as the ‘value’ like I did for the color prop. I simply couldn’t use it in the property key.

I attempted to pass in theme in a different way but was unsuccessful. Once again, Material-UI (which uses JSS) has working syntax for this method.

Resources

JSS Selectors and Syntax Rules Explained

Code Sandbox Link

Share this post:

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.