# Styled Components
> This is a **web-specific** API and you **won't** be able to use it in react-native.
---
## Referring to other components
> This is a **web-specific** API and you **won't** be able to use it in react-native.
There are many ways to apply contextual overrides to a component's styling. That being said,
it rarely is easy without rigging up a well-known targeting CSS selector paradigm
and then making them accessible for use in interpolations.
styled-components solves this use case cleanly via the "component selector" pattern. Whenever
a component is created or wrapped by the `styled()` factory function, it is also assigned a
stable CSS class for use in targeting. This allows for extremely powerful composition patterns
without having to fuss around with naming and avoiding selector collisions.
A practical example: here, our Icon component defines its response to the parent Link being hovered:
```react
const Link = styled.a`
display: flex;
align-items: center;
padding: 5px 10px;
background: papayawhip;
color: #BF4F74;
`;
const Icon = styled.svg`
flex: none;
transition: fill 0.25s;
width: 48px;
height: 48px;
${Link}:hover & {
fill: rebeccapurple;
}
`;
const Label = styled.span`
display: flex;
align-items: center;
line-height: 1.2;
&::before {
content: '◀';
margin: 0 10px;
}
`;
render(
);
```
We could have nested the color-changing rule within our Link component, but then we'd have to
consider both sets of rules to understand why Icon behaves as it does.
### Caveat
This behaviour is only supported within the context of _Styled_ Components:
attempting to mount `B` in the following example will fail because component
`A` is an instance of `React.Component` not a Styled Component.
```tsx
class A extends React.Component {
render() {
return
}
}
const B = styled.div`
${A} {
}
`
```
The error thrown - `Cannot call a class as a function` - occurs because the
styled component is attempting to call the component as an interpolation function.
However, wrapping `A` in a `styled()` factory makes it eligible for interpolation -- just
make sure the wrapped component passes along `className`.
```tsx
class A extends React.Component {
render() {
return
}
}
const StyledA = styled(A)``
const B = styled.div`
${StyledA} {
}
`
```
---
## Existing CSS
There are a couple of implementation details that you should be aware of, if you choose to use
styled-components together with existing CSS.
styled-components generates an actual stylesheet with classes, and attaches those classes to
the DOM nodes of styled components via the `className` prop.
It injects the generated stylesheet at the end of the head of the document during runtime.
### Styling normal React components
If you use the `styled(MyComponent)` notation and `MyComponent` does not
render the passed-in `className` prop, then no styles will be applied.
To avoid this issue, make sure your component attaches the passed-in `className` to a DOM node:
```tsx
class MyComponent extends React.Component {
render() {
// Attach the passed-in className to the DOM node
return
}
}
```
If you have pre-existing styles with a class, you can combine the global class with the
passed-in one:
```tsx
class MyComponent extends React.Component {
render() {
// Attach the passed-in className to the DOM node
return
}
}
```
### Issues with specificity
If you apply a global class together with a styled component class, the result might not be
what you're expecting. If a property is defined in both classes with the same specificity,
the last one will win.
```tsx
// MyComponent.js
const MyComponent = styled.div`background-color: green;`;
// my-component.css
.red-bg {
background-color: red;
}
// For some reason this component still has a green background,
// even though you're trying to override it with the "red-bg" class!
```
In the above example the styled component class takes precedence over the global class, since
styled-components injects its styles during runtime at the end of the `` by default.
Thus its styles win over other single classname selectors.
One solution is to bump up the specificity of the selectors in your stylesheet:
```css
/* my-component.css */
.red-bg.red-bg {
background-color: red;
}
```
### Avoiding conflicts with third-party styles and scripts
If you deploy styled-components on a page you don't fully control, you may need to take
precautions to ensure that your component styles don't conflict with those of the host page.
The most common problem is insufficient specificity. For example, consider a host page with this
style rule:
```css
body.my-body button {
padding: 24px;
}
```
Since the rule contains a classname and two tag names, it has higher specificity than the single
classname selector generated by this styled component:
```tsx
styled.button`
padding: 16px;
`
```
There's no way to give your components complete immunity from the host page's styles, but you can
at least boost the specificity of their style rules with
[babel-plugin-styled-components-css-namespace](https://github.com/QuickBase/babel-plugin-styled-components-css-namespace),
which allows you to specify a CSS namespace for all of your styled components. A good namespace
would be something like `#my-widget`, if all of your styled-components render in a container
with `id="my-widget"`, since ID selectors have more specificity than any number of classnames.
A rarer problem is conflicts between two instances of styled-components on the page. You can avoid
this by defining `process.env.SC_ATTR` in the code bundle with your styled-components instance.
This value overrides the default `