Linaria - Getting Started
I had a work colleague introduce me to Linaria last week and I’ve used it on a project and I quite like it.
Linaria is like styled-components but different as in there’s no runtime cost and some other gotchas I’ve found along the way.
What does that mean though? I’m going to take the headings from the Linaria Docs for benefits and list them here, for more detail on them I suggest checking the links in the list.
Advantages Over other CSS-in-JS solutions
Example Me Up Yo!
TL;DR to the video if you like, or read on…
Getting started with Linaria, I’m using the Gatsby default starter (no surprises there I guess 🤣).
I like styled-components because you’re writing CSS not camelCase style keys.
To start I’ll spin up a new project with the Gatsby CLI:
1# with the Gatsby CLI2gatsby new gatsby-starter-linaria3# or with npx4npx gatsby new gatsby-starter-linaria
Add Linaria and the Gatsby plugin as dependencies:
1yarn add linaria@next gatsby-plugin-linaria
Error: Cannot find module ‘core-js/…’
I’m using @next
because there’s a known issue between Linaria and
Gatsby’s version of core-js.
I’ll add the .linaria-cache
folder to bottom of the .gitignore
file as that’s not needed in source control.
1# linaria2.linaria-cache
Add gatsby-plugin-linaria
to the gatsby-config.js
file in the
plugins
array:
1plugins: [2 `gatsby-plugin-linaria`,3 `gatsby-plugin-react-helmet`,4 {5 resolve: `gatsby-source-filesystem`,6 ...
The ...
represents the reset of the items in the array, I’ve
shortend it for brevity.
I’ll delete the layout.css
file in the components directory and
remove the import "./layout.css"
line from the layout.js
component.
Now that the reset is removed (when I deleted the layout.css
file)
there’s a bit of a margin showing and everything looks a bit meh!
Global Style
With CSS-in-JS the styles can be scoped to specific components, more on this in a bit.
Sometimes there’s a need to write some global styles, to get rid of that margin and to normalise browser inconsistencies.
I’ll straight up jack the example given in the Linaria docs and add
that to a theme
folder in the src
directory. The file structure
will look like this.
1gatsby-starter-linaria/2├─ src/3│ ├─ components4│ ├─ images5│ ├─ pages6│ └─ theme7│ └─ globals.js
In the globals.js
file, I’ll import the css
tag from Linaria and
paste in the example.
Add a body
tag to remove that margin and add a background
colour
with a bit of contrast so that I can see the styles have been applied.
1import { css } from 'linaria'2
3export const globals = css`4 :global() {5 html {6 box-sizing: border-box;7 }8
9 *,10 *:before,11 *:after {12 box-sizing: inherit;13 }14
15 body {16 margin: 0;17 background: red;18 }19 }20`
Ok, cool, so that’s nice, but wtf do I do with it? Right??
So, from what I can glean the css
tag will append the global style
to the body
element of the project no matter where you put it. 🙃
For me it’ll make sense to add it to the layout
component as this is
where all the main styles for this project live and it’s what wraps
every other component and page in the project.
For now I’ll change the empty fragment (<></>
) wrapping the layout
component to a div and add a className
to it to pass the globals
to:
1...2import { globals } from "../theme/globals"3...4
5return (6 <div className={globals}>7 <Header siteTitle={data.site.siteMetadata.title} />8 <div9 style={{10 margin: `0 auto`,11 maxWidth: 960,12 padding: `0 1.0875rem 1.45rem`,13 }}14 >15 <main>{children}</main>16 ...
I can now take some of the styles from the reset I deleted and add
those to the globals
file:
1import { css } from 'linaria'2
3export const globals = css`4 :global() {5 html {6 box-sizing: border-box;7 font-family: sans-serif;8 -ms-text-size-adjust: 100%;9 -webkit-text-size-adjust: 100%;10 }11
12 *,13 *:before,14 *:after {15 box-sizing: inherit;16 }17
18 body {19 margin: 0;20 -webkit-font-smoothing: antialiased;21 -moz-osx-font-smoothing: grayscale;22 }23 }24`
Now the styles are back to what they were but I’m now using Linaria.
Using the styled
tag
Now I can use the Linaria styled
tag much in the same way I’d use it
with styled-components.
I’m going to convert the components from using the inline style
tag
to using the Linaria styled
tag.
I’ll work through the components that have styles in them.
Header: I’ll import the Linaria styled
tag and make a
StyledHeader
component:
1import { styled } from 'linaria/react'2
3const StyledHeader = styled.header``
From here I can add all the styles in that wrapping component to the
styled
Linaria tag component.
So I’ll add a div
a h1
and an a
tag (the Gatsby Link
component
is an a
element) like this:
1const StyledHeader = styled.header`2 background: rebeccapurple;3 margin-bottom: 1.45rem;4 div {5 margin: 0 auto;6 max-width: 960px;7 padding: 1.45rem 1.0875rem;8 }9 h1 {10 margin: 0;11 }12 a {13 color: white;14 text-decoration: none;15 }16`
Now the component is cleaner with all the inline styling moved to the
styled
Linaria component.
1const Header = ({ siteTitle }) => (2 <StyledHeader>3 <div>4 <h1 style={{ margin: 0 }}>5 <Link to="/">{siteTitle}</Link>6 </h1>7 </div>8 </StyledHeader>9)
Layout: same again, import the Linaria styled
tag and make a
StyledLayout
component:
1import { styled } from 'linaria/react'2
3const StyledLayout = styled.main``
As this is wrapping the whole project I’ll need to define a class for
the div
on this component:
1const StyledLayout = styled.main`2 .page-wrapper {3 margin: 0 auto;4 max-width: 960px;5 padding: 0 1.0875rem 1.45rem;6 }7`
Apply the class to the div in the component and remove the main
tag
wrapping the components children
:
1return (2 <StyledLayout className={globals}>3 <Header siteTitle={data.site.siteMetadata.title} />4 <div className="page-wrapper">5 <>{children}</>6 <footer>7 © {new Date().getFullYear()}, Built with8 {` `}9 <a href="https://www.gatsbyjs.org">Gatsby</a>10 </footer>11 </div>12 </StyledLayout>13)
That’s it for the components and taking a look at the pages none of them have any styles in them.
So now the StyledLayout
is where I could apply the styles to the
h1
and p
elements in the pages. If I wanted to I could style the
rest of the projects elements here.
But I’m not! That’s it for this one.
Video Detailing the Process
Here’s a video of me detailing the process.
Resources
Here’s some resources on CSS-in-JS performance I found interesting.
Back to Top