CSS and React Components
Where Stimulus encourages using the markup we are already writing, therefore keeping CSS in its own separate files, React encourages thinking about CSS and code together. Once we get in the habit of thinking of our page as made up of a number of different React components, it’s a small step to imagine those components containing their own CSS for features that are specific to that component.
Including CSS with React code is so common that there are many libraries that can handle this. We’re going to talk about one of these libraries that has an interesting way to insert CSS into our React code: the styled-components library.
The styled-components library allows us to define React components that include CSS styles inside the definition of the component. When the component renders, the styled-components library generates CSS code with definitions for these styles and uses those generated CSS class names in the rendered HTML markup.
In practice, this means that we’re not attaching CSS definitions to the big components we’ve already defined. Rather, we’re attaching them to the internal markup of the components that use
span is replaced with styled-components that define their own CSS.
CSS with React Components
Why would we do this if CSS seems good enough? CSS is great, but there are a few reasons why it’s helpful to bundle CSS with React components:
It’s easier to see what CSS applies to a component because the styling is right there in the same file as the component. There tends to be a better separation of styling from logic and, as a result, the logic components tend to be a little cleaner. The library gives us some protection against style bugs, such as using the wrong CSS class. It also prevents unused CSS from being sent to the page. The styled-components library has strong support for global properties. There are also a few challenges associated with bundling CSS with React components:
- It’s easier to see what CSS applies to a component because the styling is right there in the same file as the component.
- There tends to be a better separation of styling from logic and, as a result, the logic components tend to be a little cleaner.
- The library gives us some protection against style bugs, such as using the wrong CSS class. It also prevents unused CSS from being sent to the page.
- The styled-components library has strong support for global properties.
There are also a few challenges associated with bundling CSS with React components:
- Syntax is problematic, especially for dynamic properties and especially with TypeScript. We’ll probably want an editor plugin to help.
- It can be difficult to debug the resulting CSS without additional plugins.
- It can encourage an overreliance on
divs that make the layout harder to manage long term.
Overall, though, styled-components are interesting and worth considering in our project. Let’s add some.
With TypeScript, we have to install two packages, and we’re going to install an optional third package that will give us slightly better tooling in development:
yarn add styled-components
yarn add @types/styled-components
yarn add babel-plugin-styled-components --dev
We need to add the Babel plugin to the
plugins section of the
babel part of our
babel section now looks like this:
Now we can use the styled-components library on the components that we added with React.
Our First Styled Component
Let’s look at our React components and see how we can use the styled-components library. As a reminder from Managing State in React, we currently have four components with display elements on our concert view page: a
VenueHeader that adds a header, a
VenueBody that controls the grid, a
Row that manages a row of seats, and a
Seat that draws an individual seat.
Our first styled-components change is in
VenueHeader. We want to change the styling of the text prompt and manage the spacing a bit. Otherwise, the functionality is the same: when the option changes, we pass the new value back to the same
ticketsToBuyChanged handler, stored in the
Venue component and passed to
VenueHeader via a prop.
Right at the top of the file we import
styled-components. Then the real action comes with our declaration of