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-linariaAdd Linaria and the Gatsby plugin as dependencies:
1yarn add linaria@next gatsby-plugin-linariaError: 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-cacheAdd 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.jsIn 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