React Styled Components — Existing CSS and Template Tags

John Au-Yeung - Jan 23 '21 - - Dev Community

Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62

Subscribe to my email list now at http://jauyeung.net/subscribe/

React is the most used front end library for building modern, interactive front end web apps. It can also be used to build mobile apps.

In this article, we’ll look at how to deal with existing CSS so that they don’t conflict with styled-components created with styled-components ‘s styles. Also, we look at how to refer to other components.

Existing CSS

We can pass in class names that are generated with styled-components in addition to the ones that are generated else in the same code. This applies to components that are created with the styled(Component) function.

For instance, we can do that as follows:

styles.css :

.lightgreen {
  background-color: lightgreen;
}
Enter fullscreen mode Exit fullscreen mode

App.js :

import React from "react";
import styled from "styled-components";
import "./styles.css";

const Foo = ({ className }) => {
  return <div className={`lightgreen ${className}`}>foo</div>;
};

const StyledFoo = styled(Foo)`
  color: green;
`;

export default function App() {
  return (
    <div>
      <StyledFoo>foo</StyledFoo>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

In the code above, we have the StyledFoo component, which is created from the Foo component. Since we called styled(Foo) , we’ll have access to the className prop that’s generated when we called that in Foo .

Now we can combine class names from another CSS file as we did with styles.css and the className generated from styled-components via the className prop as we have in Foo .

Therefore, we have ‘foo’ in green with a light green background.

Issues with Specificity

The example above doesn’t have conflicting styles. However, we often have conflicting styles from the CSS and what we have in the styles component created with styled-components .

For instance, if we have the following example:

styles.css :

.red {
  color: red;
}
Enter fullscreen mode Exit fullscreen mode

App.js :

import React from "react";
import styled from "styled-components";
import "./styles.css";

const StyledFoo = styled.div`
  color: green;
`;

export default function App() {
  return (
    <div>
      <StyledFoo className="red">foo</StyledFoo>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

The styles from the red class take precedence over the green color in the StyledFoo component since it’s injected directly into the component.

By the rule of specificity, the styles that are injected nearest the component we’re styling will take precedence.

If we want to keep the styles of the StyledFoo component, then we move it outside the StyledFoo component.

We can avoid conflicts by namespacing the CSS class names that are generated by styled-components . To do that, we use the babel-plugin-styled-components-css-namespace plugin.

We just have to install it by running:

npm install @quickbaseoss/babel-plugin-styled-components-css-namespace
Enter fullscreen mode Exit fullscreen mode

Then add it to the Babel configuration as follows:

"babel": {
  "plugins": [
    "@quickbaseoss/babel-plugin-styled-components-css-namespace"
  ]
}
Enter fullscreen mode Exit fullscreen mode

Tagged Template Literals

Tagged Template Literals are new to ES6. The following code are the same:

foo `string`
foo(['string'])
Enter fullscreen mode Exit fullscreen mode

where foo is a function like:

const foo = () => {}
Enter fullscreen mode Exit fullscreen mode

styled-components returns new components with the styles added by passing in the CSS string into the tags and then doing its own processing to return a new component.

Referring to Other Components from a Component

A styled component created with styled-component can refer to another component in its style. For instance, we can write the following code to do that:

import React from "react";
import styled from "styled-components";
import "./styles.css";

const Foo = styled.div`
  color: green;
`;

const HoveredFoo = styled.div`
  ${Foo}:hover {
    color: red;
  }
`;

export default function App() {
  return (
    <div>
      <HoveredFoo>
        <Foo>foo</Foo>
      </HoveredFoo>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

In the code above, we created a Foo component that styles the content red. Then we created the HoveredFoo component which makes Foo green when we hovered over it.

Then if we wrap HoveredFoo around Foo , we’ll see that it’s green when our mouse isn’t over ‘foo’, but it’ll turn red if we hover the mouse over it.

Conclusion

We can deal with existing CSS either by combining the class names that are generated from styled-components with existing class names.

Also, we can use the @quickbaseoss/babel-plugin-styled-components-css-namespace Babel plugin to namespace the classes that are generated with styled-components .

Finally, we can refer to other components in the styles of another component created with styled-component .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .