How many times have you looked at your code looking for a specific div, and wasted several minutes until you found it. Or maybe you didn't event find it and tried searching the div by the class you used to style it, but oops, you don't really remember de name of the class. It sucks right?
Styled Components to the rescue
This is my experience using Styled Components, a CSS library which gives you a lot of power when implementing CSS code.
Cool thing number 1
Imagine you have the following component:
const Component = () => (
<div class='container'>
<div class='header'>
<p>some text</p>
</div>
<main>
<div class='main_left'>
<p>some text</p>
</div>
<div class='main_right'>
<p>some text</p>
</div>
<main>
<div class='footer'>
<p>some text</p>
</div>
</div>
)
Very simple right?
Now picture this:
import styled from 'styled-components'
const Container = styled.div`
// css code here
`
const MainLeft = styled.div`
// css code here
`
const MainRight = styled.div`
// css code here
`
const Footer = styled.div`
// css code here
`
const Component = () => (
<Container active>
<Header>
<p>some text</p>
</Header>
<main>
<MainLeft>
<p>some text</p>
</MainLeft>
<MainRight>
<p>some text</p>
</MainRight>
<main>
<Footer>
<p>some text</p>
</Footer>
</Container>
)
Much cleaner right? Notice that the components generated are not real components (they are styling components) in which you can generate JS logic, it's just CSS code definition wrapping a HTML tag and exported with a easy-to-find name.
The way I see it is like: HTML tag + class_name = StyledComponent
Cool thing number 2
Something to have in mind is: it's reusable! and flexibly reusable.
Why flexibly reusable?
On the one hand, you can declare the styled components in another JS file and import it in any React component.
On the other hand, you can also do this:
Imagine a situation in which you have a select HTML tag and a button HTML tag that, at the end, you want them to look the same. You have already finished styling the select tag and you are about to start with the button tag. WAIT, try this.
Of course, you first declare the Select styled component styles.
const Select = styled.select`
width: 400px;
height: 400px;
background-color: blue;
border: 1px solid red;
`
After doing this you can inherit all the styles from this Select component wherever you want, in another HTML element.
I use bold in styles because it's all that it inherits, the CSS, so:
width: 400px;
height: 400px;
background-color: blue;
border: 1px solid red;
Let's continue
const Select = styled.select`
width: 400px;
height: 400px;
background-color: blue;
border: 1px solid red;
`
Imagine you want a button
with the same styles as the Select. In the component you would use it like this:
const Component = () => (
<Select as="button" />
)
What we are saying in the Button declaration is: take all the styles from Select and but renders it as a button HTML tag. Note that the attributes that now Select recieves are the ones that a HTML button tag would. (so, no options).
Cool thing number 3
Now imagine you need to conditionaly colour a p HTML tag depending on some state you have in your component, something like this:
const Component = () => {
const someCondition = useState(false)
return (
<p className={`base ${someCondition ? 'when_true' : 'when_false'}`}>some text</p>
)
}
So, what do I see wrong here.
Couple of things:
- You need to define 2 classes (one for condition true and one for false)
- You will possibly have to create 3 classes (one for the base styles of the p HTML tag, one for the styles that are applied only when the condition is true and one for the styles that applied only when the condition is false)
In normal CSS code:
<style>
.base {
background-color: grey;
font-size: 1.5rem;
font-weight: bold;
}
.when_true {
color: blue;
}
.when_false {
color: red;
}
</style>
Now with the power of Styled Components props:
import styled from 'styled-components'
const Paragraph = styled.p`
background-color: grey;
font-size: 1.5rem;
font-weight: bold;
color: ${props => props.conditionName ? 'blue' : 'red'}
`
const Component = () => {
const [someCondition, setSomeCondition] = useState(false)
return (
<Paragraph conditionName={someCondition}>some text</Paragraph>
)
}
Top comments (2)
Nice article! Just an advice to avoid looking for a specific div. There are a lot of tags in html that have meaning like main, header, nav, footer, ... It helps organizing your markup and makes the information more accessible for screen reader I guess 👍
totally man. I just used div as it's the most common one and anyone who's new to programming can relate. Thanks for the advice