内容简介:Styled Components is one of those interesting topics that developers love to argue about. It's a brand new way of doing things that many people just aren't ready to acknowledge. Regardless, just because something is different doesn't mean it isn't worth a
Styled Components is one of those interesting topics that developers love to argue about. It's a brand new way of doing things that many people just aren't ready to acknowledge. Regardless, just because something is different doesn't mean it isn't worth a try.
Table of Contents
- What and Why - Styled Components
- Install The Styled Components Library
- Create Styled Component for Container
- Create Styled Components for Navbar
- Create Styled Components for Split Component
- Create Styled Components for Pricing Page
In this article, we are going to convert a React site using regular CSS to one that uses Styled Components. Don't worry... if you don't like it, you never have to use it again!
What and Why - Styled Components
Again, Styled Components are debated by many, but there are some pretty cool benefits.
- automatic vendor prefixing
- scoping for CSS
- leverage JavaScript syntax for dynamic CSS
- benefits of a pre-compiler like variables and nesting
You can find more on the Styled Components Motivation Page .
Lots of people debate about whether or not JS in CSS is a good idea. Just do whatever works best for you and your team!
Personally, I like the idea of Styled Components for two main reasons. First, I get to treat my styles like everything else in my React projects, a component. I can pass properties, reuse them, etc. It just feels nice!
Additionally, I get to leverage JavaScript syntax that I am already familiar with to add dynamic updates to my CSS. One of the things that bothered me about pre-compilers (LESS, SASS, etc.) is that they each have their own syntax for certain things on top of CSS. With Styled Components, I just write JavaScript for those additional features.
There are two projects in Code Sandbox that you can use, a starter project and a finished project . The starter project is setup with React Router and has a navbar that links to two different pages, the home page and the pricing page. Although there are other links in the navbar, they don't work . They are just there for demo purposes .
Install The Styled Components Library
Before we create a Styled Component we need to install the library. You can do this by running the following command in the terminal or using the GUI in Code Sandbox.
npm install styled-components
With the package installed, our goal is to clear our the index.css
file in the starter project by converting fully to Styled Components. In the end, both projects have the same functionality.
Let's get moving!
Create Styled Component for Container
Let's start with something simple, a container of wrapper for our app. First, create a folder called Styled
in the src
directory. We will store all of our Styled Components inside of this directory.
Then, create a file called Container.js
inside of that directory. Now, import the styled object from the library.
import styled from 'styled-components';
To create a Styled Component we use styled
follow by a period and then the type of DOM element we are trying to style. In this case a div
. Then we use tagged template literals (open and close backticks) to put our styles inside of. You can copy all the styles that we reference from here or from the starter files.
Make sure your styled components are capitalized so that React can recognize them as custom components.
export const Container = styled.div` max-width: 90vw; margin: 0 auto; `
Congrats, you created your first component. Now, we need to use it. Inside of the App.js
page, we need to import the Container Styled Component.
import { Container } from "./Styled/Container";
Then replace the existing div
with a className of container
with your actual Container component like so.
<div className="container"> <Route path="/" exact component={Home} /> <Route path="/pricing" component={Pricing} /> </div>
becomes
<Container> <Route path="/" exact component={Home} /> <Route path="/pricing" component={Pricing} /> </Container>
Not so bad huh? We are basically going to do this through the rest of our app, ripping out all of the CSS from the index.css
file into their own Styled Components. We will also learn a few cool tricks along the way!
Create Styled Components for Navbar
Now, let's look at the Navbar. Here's the starter CSS.
.nav { display: flex; padding: 20px; align-items: center; margin-bottom: 40px; } @media (max-width: 786px) { .nav { flex-direction: column; } } .nav-brand { flex-grow: 1; font-size: 24px; font-weight: 700; color: #333; text-decoration: none; } .nav-items { list-style: none; padding-inline-start: 0; display: flex; align-items: center; } .nav-item { margin-right: 20px; cursor: pointer; transition: 250ms; cursor: pointer; color: #333; text-decoration: none; } .nav-item:hover { transform: scale(1.05); } .link-button { padding: 10px 10px; border: none; border-radius: 5px; cursor: pointer; border: 1px solid #663399; } .link-button-primary { background: #663399; color: white; }
Based on that, we need to create several components.
- Nav
- NavBrand
- NavItems
- NavItem (with hover)
- NavItemButton (with additional properties for primary)
So, let's start from the top. Create a new file in the Styled
directory called Navbar.js and import styled
at the top. Now, let's create the Nav component. It's a nav
DOM element, so it will look like this.
export const Nav = styled.nav` `
Now, we can basically copy over our nav styles.
export const Nav = styled.nav` display: flex; padding: 20px; align-items: center; margin-bottom: 40px; @media (max-width: 786px) { flex-direction: column; } `;
As you can see, we even nested in our media query just like you would with a pre-compiler. Pretty cool huh? Nesting is one of my favorite features!
Nesting your styles is one of my favorite features and helps with readability and organization
Next up is the NavBrand, but the problem is that this is actually a Link component from React Router instead of a basic DOM element. No worries, we can tweak our syntax to style the Link component directly like so. Make sure, you import Link at the top of your file.
export const NavBrand = styled(Link)` `;
From there, now we just copy over our styles again.
export const NavBrand = styled(Link)` flex-grow: 1; font-size: 24px; font-weight: 700; color: #333; text-decoration: none; `;
Now for the NavItems component which will style a ul
element.
export const NavItems = styled.ul` list-style: none; padding-inline-start: 0; display: flex; align-items: center; `;
Now NavItem which is also styling the Link
component as the NavBrand did above. Notice, also that we are able to nest the hover state right inside of the component itself.
export const NavItem = styled(Link)` margin-right: 20px; cursor: pointer; transition: 250ms; cursor: pointer; color: #333; text-decoration: none; &:hover { transform: scale(1.05); } `;
And lastly, the NavItemButton. We want this element to include all of the styles we just defined for NavItem
in addition to a few more. In this case, we can extend the NavItem
component like so.
export const NavItemButton = styled(NavItem)` padding: 10px 10px; border: none; border-radius: 5px; cursor: pointer; border: 1px solid #663399; /* add additional styles for primary*/ `;
This works well for a regular NavItemButton, but what if we wanted one that adds even a few more special properties? Since these are basically React components, they can accept props just like any other component. Because of that, we can add some JavaScript to check whether or not the button has a property of primary
, and if so, add a few more properties. Here's how we do it.
export const NavItemButton = styled(NavItem)` padding: 10px 10px; border: none; border-radius: 5px; cursor: pointer; border: 1px solid #663399; /* add additional styled if primary*/ ${(props) => props.primary && css background-color: #663399; color: white; }; `
The syntax might look a bit funky, so let's explain. We define a function that takes in props and then returns a bit of css if that primary
property is present. To define the additional CSS, we use the css
object from the styled-components
library. Make sure to import it at the top.
import styled, { css } from 'styled-components';
This is part of the beauty of Styled Components. Use the JavaScript skills that you already know to customize your CSS dynamically. You can check the final version of these componts in the finished source code.
You will also need to update your Navbar component to use these new Styled Components.
import React from 'react'; import { Nav, NavBrand, NavItems, NavItem, NavItemButton } from '../Styled/Navbar'; export default function NavbarStyledComponents() { return ( <Nav> <NavBrand to="/">Cool Product</NavBrand> <NavItems> <NavItem to="/pricing">Pricing</NavItem> <NavItem>Docs</NavItem> <NavItemButton>Log in</NavItemButton> <NavItemButton primary>Get Started For Free</NavItemButton> </NavItems> </Nav> ); }
Create Styled Components for Split Component
Now on to the Split Component which is used on the home page to create a 50/50 split between two divs of content. Start by creating the Split.js
file inside of the Styled
directory.
We will need to create three different components here.
- Split
- SplitTitle
- SplitImg
Import styled
at the top of the page and stub our the Split component.
export const Split = styled.div` `
Then, copy over the CSS styles. Remeber that we can still embed the media query right inside of the component.
By nesting media queries, we can explicitly see what changes occurr for that specific compenent
export const Split = styled.div` display: grid; grid-template-columns: 1fr 1fr; align-items: center; grid-gap: 20px; @media (max-width: 786px) { grid-template-columns: 1fr; } `
The last two of these are pretty simple. Hopefully, you're getting the hang of this by now.
export const SplitTitle = styled.h1` font-size: 42px; `
and
export const SplitImg = styled.img` height: 100%; width: 100%; `
Now, delete that CSS from the CSS file and update the Home
component to leverage these new Styled Components.
import React from 'react'; import computer from '../computer.png'; import { SplitImg, Split, SplitTitle } from '../Styled/Split'; export default function Home() { return ( <Split> <div> <SplitTitle>Cool, Catchy Slogan</SplitTitle> <p> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Error, fugit provident. Fugit, distinctio dolor nesciunt natus quidem laborum beatae ratione accusantium hic illo quas id numquam possimus, similique odit alias. </p> <p> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Error, fugit provident. Fugit, distinctio dolor nesciunt natus quidem laborum beatae ratione accusantium hic illo quas id numquam possimus, similique odit alias. </p> </div> <div> <SplitImg src={computer} alt="" /> </div> </Split> ); }
Create Styled Components for Pricing Page
The next major section is for the Pricing Page. Here's the components that we need to create.
- Pricing (containers for PricingCards)
- PricingCard
- PricingTitle
- PricingFeatures
- Price
Create the Pricing.js
file inside of the Styled
directory, then start with the Pricing component. This use CSS Grid to show three different PricingCards.
export const Pricing = styled.div` display: grid; grid-template-columns: repeat(3, 1fr); grid-gap: 10px; `
Now for the PricingCard itself. This component also has a hover effect, so we can throw it right inside of the component itself.
export const PricingCard = styled.div` background: white; padding: 20px; border-radius: 5px; box-shadow: 1px 1px 5px #ccc; text-align: center; &:hover { box-shadow: 3px 3px 5px #ccc; transform: translateY(-2px); }; `
I'm sure this process is getting a bit old, so here are the last three components. There's nothing special about these, although you should be aware of the DOM elements they are targeting.
export const PricingTitle = styled.h2` text-align: center; font-weight: 300; ` export const PricingFeatures = styled.ul` text-align: left; margin-bottom: 60px; ` export const Price = styled.span` text-align: center; font-size: 54px; margin-top: 30px; margin-bottom: 60px; `
Now that these components are defined, update the JSX in the Pricing
page to use these instead of the CSS classes we used previously.
<Pricing> <PricingCard> <PricingTitle>Free</PricingTitle> <p> <Price>$0</Price>/month </p>{' '} <PricingFeatures> <li>Lorem ipsum</li> <li>Lorem ipsum</li> <li>Lorem ipsum</li> </PricingFeatures> <Button>Get Started</Button> </PricingCard> <PricingCard> <PricingTitle>Standard</PricingTitle> <p> <Price>$10</Price>/month </p>{' '} <PricingFeatures> <li>Lorem ipsum</li> <li>Lorem ipsum</li> <li>Lorem ipsum</li> </PricingFeatures> <Button primary>Get Started</Button> </PricingCard> <PricingCard> <PricingTitle>Enterprise</PricingTitle> <p> <Price>$100</Price>/month </p> <PricingFeatures> <li>Lorem ipsum</li> <li>Lorem ipsum</li> <li>Lorem ipsum</li> </PricingFeatures> <Button>Get Started</Button> </PricingCard> </Pricing>
With all of those components created, we've still got a little bit of CSS to clean up.
body { margin: 0; font-family: sans-serif; color: #333; background: #eee; }
In React using Styled Components, we can't directly target the body
element, so this is where the concept of Global Styles comes into play. We can use the createGlobalStyle
object from the styled-components
library to generate the typical "non-scoped" CSS that we started with originally. This is exactly what we need to finish out this migration.
Create a new file called Global.js
insdie of the Styled
directory and import createGlobalStyle
. We can then use it to define the global CSS for our project.
export const GlobalStyle = createGlobalStyle` body { margin: 0; font-family: sans-serif; color: #333; background: #eee; }; `
Now, we need to import these styles somewhere in our app. We can do this in our App.js
file by just including the component just inside the Router
tag.
import React from "react"; import Navbar from "./components/Navbar"; import { BrowserRouter as Router, Route } from "react-router-dom"; import Home from "./pages/Home"; import Pricing from "./pages/Pricing"; import { Container } from "./Styled/Container"; import { GlobalStyle } from "./Styled/Global"; function App() { return ( <Router> <GlobalStyle /> <Navbar /> <Container> <Route path="/" exact component={Home} /> <Route path="/pricing" component={Pricing} /> </Container> </Router> ); } export default App;
I'm sure that seemed a bit repetitive, but I think that's the point. Once you do it a few times, you get used to it pretty quickly and breeze through it. Styled Components are just a different way to write CSS in React that come with a few extra benefits.
So, are you using Styled Components? Are you an advocate for CSS in JS? Or are you on the opposite side of the fence? Let us know in the comments!
Like this article? Follow @jamesqquick on Twitter
以上所述就是小编给大家介绍的《Converting CSS In React to Styled Component》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
UNIX网络编程
史蒂文斯、芬纳、鲁道夫 / 杨继张 / 清华大学出版社 / 2006-1 / 98.00元
《UNIX网络编程》(第1卷)(套接口API第3版)第1版和第2版由已故UNIX网络专家W. Richard Stevens博士独自编写。《UNIX网络编程》(第1卷)(套接口API第3版)是3版,由世界著名网络专家Bill Fenner和Andrew M. Rudoff执笔,根据近几年网络技术的发展,对上一版进行全面修订,增添了IPv6的更新过的信息、SCTP协议和密钥管理套接口的内容,删除了X......一起来看看 《UNIX网络编程》 这本书的介绍吧!