Project 41 of 100 - Writing Responsive CSS in JSX
Tags: react, 100daysofcode, javascript
Published: 2021-01-30 07:26:54

*Hey! I'm on a mission to make 100 React.js projects ending March 8th. Please follow my dev.to profile or my [twitter](https://www.twitter.com/jwhubert91) for updates and feel free to reach out if you have questions. Thanks for your support!*

Link to today's deployed app: [Link](https://www.dolcesdollhouse.com/)
Link to the repo: [github](https://github.com/jwhubert91/dolces-dollhouse)

This was a short project riding the heels of the first draft of a client website. The website is optimized for mobile but we wanted to just put a couple of styles in so that it's comprehensible to desktop viewers. The primary challenge was the static background image element saying (paraphrased from Spanish) "More coming soon".

For mobile screens I wanted to take advantage of the `background-size: cover` CSS property to simply cover the space. On quite large screens though this can look ridiculous since only maybe a small part of the image will be showing.

In pure CSS this is easily solved by a media query. Simply state the screen size you are optimizing for (say- over 570px wide) and set the styles within the brackets.

In this project I am actually making use of `props` to pass an image URL to the component so that the component is reusable. Since I'm setting the CSS `background` property within the JSX, it would override some of the other styles in actual stylesheet.

The CSS is loaded in the <head> of the html page well before the image URL is passed to this object so this got in the way of me being able to give the image the `background-size: cover` style.

Instead, we can use Javascript to check for the screen size with the following built-in vanilla Javascript property of the `window` object:

```
window.innerWidth
```

This property returns the inner width of the window thus allowing you to set styles for different screen sizes. 

The problem? Well this property is only called once on page load. Frankly for mobile this is just fine, but if someone is looking at it on a browser and decides to resize the window and push it to the side, it won't be called again. To call the property again when the window is resized we take advantage of a callback on the `window.onresize` method. I am using React `useState` to set a windowWidth variable to the size of the screen on page load and whenever the screen is resized.

```
  const [windowWidth,setWindowWidth] = useState(0);

  window.onresize = () => {
    setWindowWidth(window.innerWidth);
  }
```

Now that we have a variable that updates whenever the screen changes sizes we can create separate style objects to pass to the JSX element for each screen size, like here, where I use a ternary:

```
  const innerImageStyle = windowWidth < 570 ?
   ({
    width: '100%',
    height: '80vh',
    backgroundImage: `url(${props.imageUrl})`,
    backgroundSize: 'cover',
  }) : 
   ({
    width: '100%',
    height: '500px',
    backgroundImage: `url(${props.imageUrl})`,
    backgroundSize: 'contain',
  });
```

As you can see if it's a mobile device (less than 570 pixels wide) then we want the background to cover the space available. If it's a desktop computer, we want the background to repeat (client's choice here but I like it).

I'm sure we could also do this using the React useEffect hook, but this is intended to be a simple version and I honestly feel like the built-in Javascript window methods are underestimated and under-taught for how powerful they are.

Let me know what you think and how you do conditional styling for React components in the comments...