React and CSS

Standard approach to CSS

In a previous post we looked at an animated button and the issue(s) of having CSS in a separate .css file.

To recap, CSS can be implemented in a standalone .css file, for example AniButton.css might look like this (this is an abridged version of the CSS used in the previous post)

.button {
  background: #2B2D2F;
  height: 80px;
  width: 200px;
  text-align: center;
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  left: 0;
  right: 0;
  margin: 0 auto;
  cursor: pointer;
  border-radius: 4px;
}

This can then be imported into our React jsx/tsx file using

import "AniButton.css"

and everything works as per standard CSS. A couple of downsides to this are the CSS is in global namespace and also we’re using another language/DSL to define CSS whereas, it’d be nice if we could do all this in one language, i.e. in this case JavaScript/TypeScript.

Inline the style

From this global approach we can look towards inline of the CSS and also at the same time, removing the different language/DSL issue by declaring CSS in a JavaScript JSON style object, for example we remove the .CSS file and it’s import and then include the CSS style as an object, like this

const styles = {
  button: {
    background: "#2B2D2F",
    height: "80px",
    width: "200px",
    textAlign: "center",
    position: "absolute",
    top: "50%",
    transform: "translateY(-50%)",
    left: "0",
    right: "0",
    margin: "0 auto",
    cursor: "pointer",
    borderRadius: "4px"
  }
};

to apply this style we will need to add a style attribute to each of the elements we want a style applied to, for example

<div className="button" style={styles.button}>
</div>

One obvious downside of this inclusion of CSS along with our code is the separation of concerns might be seen as being lost, i.e. styling is now included along with the component code, however I tend to see React as lacking that separation of markup and code which you get with something like XAML/WPF, so I suppose it’s simply down to your interpretation of such things.

Styled components

Another solution which is a bit of a combination of CSS (syntax wise the names do not change to camelCase nor are values wrapped in quotes) and JavaScript is to use a library such as styled-components or emotion.

I’m going to look at Emotion’s implementation, so run the following

yarn add @emotion/styled @emotion/core

Now we can replace our button CSS and inline JavaScript CSS with style components, for example within your JSX/TSX file implement the following

import styled from '@emotion/styled'

const Button = styled.div`
  background: #2B2D2F;
  height: 80px;
  width: 200px;
  text-align: center;
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  left: 0;
  right: 0;
  margin: 0 auto;
  cursor: pointer;
  borderRadius: 4px;
`;

Now in usage our code looks like this

<Button className="button" onClick={this.handleOnClick}>
  <div className="text" style={styles.text} onClick={this.handleOnClick}>Submit</div>
</Button>