You Might Not Need styled-components
Tags: react, styledcomponents, css
Published: 2021-05-26 22:01:07

---
title: You Might Not Need styled-components
published: true
description: 
tags: #react #styledcomponents #css
cover_image: https://source.unsplash.com/6JVlSdgMacE
---

[styled-components](https://styled-components.com/) can be quite nice for whipping up components but for old farts like me that are more familiar with old-timey CSS, I prefer to use [CSS Modules](https://create-react-app.dev/docs/adding-a-css-modules-stylesheet/).

When using CSS Modules, we quickly find out that while somethings are simpler (media queries) some things are not so easy (how the $@^% do I use a theme?). 

##Theming

styled-components has a [ThemeProvider](https://styled-components.com/docs/advanced#theming) which is nice. Grab some JSON from a server somewhere and pass it to the ThemeProvider and you can use it in your styles.

We can do that, too. First, we make a Theme Context component. The entire thing is 4 lines, one line is blank and we probably don't even need the first line, anyway...

```javascript
import { createContext } from "react";

export const ThemeContext = createContext();
export const ThemeProvider = ThemeContext.Provider;
```

To use it, we import the ThemeProvider, then wrap it around some JSX that we need to style:

```jsx
import { ThemeProvider } from "./ThemeContext";

<ThemeProvider value={theme}>
  <Button>Press</Button>
</ThemeProvider>
```

Here is a simplified example of a Button component using the theme:

```javascript
import React, { useContext } from "react";
import styles from "./Button.module.css";
import { ThemeContext } from "./ThemeContext";

export const Button = (props) => {
  const theme = useContext(ThemeContext);

  const style = {
    "--bg-color": theme.backgroundColor,
    "--fg-color": theme.foregroundColor,
    ...props.style
  };

  return (
    <button
      className={styles.Button}
      style={style}
    />
  );
};
```

The values we need in the theme are passed to the CSS through the style attribute. The CSS module can use the [CSS variables](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties) like so:

```css
.Button {
  color: var(--fg-color);
  background-color: var(--bg-color);
}
```

##Adapting Based On Props

Sometimes you want to change the styles on a component based on some props. This becomes quite easy with CSS.

```jsx
<Button size="large">
  Primary Large
</Button>
```

CSS

```css
.Button {
  font-size: 14px;
}

.Button[data-size=large] {
  font-size: 16px;
}
```

##Window.matchMedia

The last trick is rather rare, but I ran into an issue where a breakpoint was not known in advance and I had to use logic in javascript to determine if a class should be added to a component or not.

[Window.matchMedia](https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia) allowed me to solve this problem.

This allowed my component to accept a `breakpoint` prop and add a CSS class if the window was sized smaller than the breakpoint.

```jsx
const maxWidth = width =>
  window.matchMedia(`(max-width: ${width}px)`).matches;

const getItemClasses = breakpoint => {
  const names = [styles.Item];
  if (maxWidth(breakpoint)) names.push(styles.ItemSmall);
  return names.join(" ");
};

return (
  <div className={getItemClasses(breakpoint)}>{children}</div>
);
```

##Conclusion

These tricks covered the features of styled-components that I used but allowed me to use CSS Modules instead. I hope you find them useful.