Introduction
Styled Components is a library for building HTML components with CSS classes, designed for use with React. It provides dynamic styling options and automatically updates styles for ease of use. The library allows for writing React components using both HTML5 and CSS, and generates CSS for improved app performance. Styles are defined in CSS and applied to elements in the application using JavaScript.
Benefits of Styled Components:
- CSS syntax remains unchanged, even when writing in a JS file.
- Improved performance with automatic addition of vendor prefixes.
- Unused CSS and styling is automatically removed.
- No need to manage CSS class naming methodology, as class names are generated automatically.
Styled components are easily integrated into a React architecture. This article explores how styled components offer a declarative approach to styling components in a React music application
, reducing the need for extensive CSS writing.
We are basically going to build the following project:
Setting Up a React Environment:
- If you have npx and Node.js installed, use create-react-app to create a React application.
- If not, visit Node.js to download the recommended version.
- To check Node installation, open terminal/command prompt and run "node -v" and "npm -v" to see the versions.
<!-- Run the command below to create a React application named my-react-music-app: -->
npx create-react-app moove
// The create-react-app will set up everything you need to run a React application.
<!-- Run the React Application: -->
// Now you are ready to run your first real React application!
// Run this command to move to the my-react-music-app directory:
cd moove
<!-- Run this command to run the React application moove: -->
npm start
Getting started
Installation:
To install styled-components, follow these steps:
- Open a new terminal tab in Visual Studio Code.
- Run the following command:
npm install styled-components
Project Structure should look like the following once our project files have been created and our dependencies have been installed:
Remove the default App.test.js, logo.svg, reportWebVitals.js, setUpTests.js along with App.css and index.css you have already created.
Notice, you'll come across an error on your local server:
A simple way to handle this error is basically to navigate to the index.js file and remove the index.css and reportWebVitals(). You will notice another compilation error at App.js because the compiler is trying to import logo.svg and App.css which we no longer have.
Navigate to App.js and remove the logo.svg and App.css.
Your first styled component
Open App.js, delete everything, and replace it with the following:
const App = () => {
return <div className="container">hello styled component</div>;
};
export default App;
Components are a new way of building web apps that harnesses the power of CSS and JavaScript.
Styling in JSX often involves adding classes using className. For example, you might have a "container" class in a CSS file to center content within a specific width. With style components, you can use a component called "Container" as a wrapper for other components, enabling nested components to have different styles.
For example, you can create a new styled component by calling the styled() function and passing in the type of HTML element you want to style as seen below;
import styled from 'styled-components';
const StyledButton = styled.button`
background-color: blue;
color: white;
font-size: 16px;
padding: 10px 20px;
border: none;
&:hover {
background-color: darkblue;
}
`;
In this example, StyledButton is a new component that can be used just like a regular HTML button, but with the added styles.
To use the StyledButton component, you can simply import it and use it in your JSX code, like so:
import StyledButton from './StyledButton';
function MyComponent() {
return <StyledButton>Click me</StyledButton>;
}
Go to the App.js file in our project's directory;
import React from "react";
const App = () => {
return <Container></Container>;
};
export default App;
The app will fail due to the "Container" component being undefined. To resolve this issue:
- Create a new folder named styles within the components folder in the src directory.
- Store all style components in the styles folder.
- Keep all other React components in the original components folder.
In the styles folder, create a new file named container.styled.js
and include the following code in your file.
import styled from "styled-components";
export const Container = styled.div`
width: 100%;
max-width: 428px;
margin: 0 auto;
height: 926px;
background-color: #000000;
overflow: hidden;
`;
We will add a ThemeProvider
that provides a theme object to the component, you can wrap your component tree with the ThemeProvider component and pass a theme object as a prop to it.
Here's an example in App.js code:
import React from "react";
import { ThemeProvider } from "styled-components";
import { Container } from "./components/styles/Container.styled";
const theme = {
colors: {
header: "#0F0F0F",
text: "#ffffff",
body: "#000000",
},
};
const App = () => {
return (
<!-- pass a theme object as a prop -->
<ThemeProvider theme={theme}>
<Container></Container>
</ThemeProvider>
);
};
export default App;
Create a file Header.js
in the component folder and add the code.
import { Logo, Nav, StyledHeader } from "./styles/Header.styled";
const Header = () => {
return (
<StyledHeader>
<Nav>
<Logo
src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q2xma02eslsv9bfw0ivl.png"
alt="profile image"
/>
</Nav>
</StyledHeader>
);
};
export default Header;
Create a file Header.styled.js
in the styles folder and add:
import styled from "styled-components";
export const StyledHeader = styled.header`
display: flex;
align-items: center;
width: 100%;
max-width: 428px;
height: 83px;
margin: 0 auto;
position: relative;
<!-- passing theme as a prop to both color and background -->
color: ${({ theme }) => theme.colors.text};
background-color: ${({ theme }) => theme.colors.header};
`;
export const Nav = styled.nav`
display: flex;
align-items: center;
justify-content: flex-start;
width: 100%;
height: 100%;
`;
export const Logo = styled.img`
position: absolute;
height: 49px;
width: 49px;
left: 23px;
top: 21px;
cursor: pointer;
`;
We'll create a file Global.styled.js
in the the styles folder using the createGlobalStyle function
from the styled-components library. This function creates a component that holds the global styles and can be used in the same way as any other styled component.
Here's an example in code:
import { createGlobalStyle } from "styled-components";
const GlobalStyles = createGlobalStyle`
*,
*:before,
*:after {
box-sizing: border-box;
padding: 0;
margin: 0;
}
body {
margin: 0;
padding: 0;
font-family: "Bw Modelica", sans-serif;
background-color: ${({ theme }) => theme.colors.text};
position: relative;
}
body::-webkit-scrollbar {
display: none;
}
`;
export default GlobalStyles;
Update App.js with the following:
import React from "react";
import { ThemeProvider } from "styled-components";
import ArtistCard from "./components/ArtistCard";
import { Container } from "./components/styles/Container.styled";
import Header from "./components/Header";
import GlobalStyles from "./components/styles/Global.styled";
const theme = {
colors: {
header: "#0F0F0F",
text: "#ffffff",
body: "#000000",
},
};
const App = () => {
return (
<ThemeProvider theme={theme}>
<>
<GlobalStyles />
<Container>
<Header />
<ArtistCard />
</Container>
</>
</ThemeProvider>
);
};
export default App;
Create a file ArtistCard.js
in the components folder and add the following:
import React from "react";
import FooterStyled from "./Footer";
import {
AppMusicCard,
BillboardBanner,
BurnaCard,
LojayCard,
ThirdBurnaCard,
SubTitle,
Title,
SecondBurnaCard,
SecondLojayCard,
FourthBurnaCard,
Text,
SubText,
BurnaTitle,
LojayTitle,
BurnaContent,
LojayContent,
ThirdBurnaTitle,
SecondLojayTitle,
Footer,
} from "./styles/ArtistCard.styled";
const ArtistCard = () => {
const cards = [
{
title: "Daily Vibes 1",
content: "Burna Boy, Oxlade, Davido, Tems Wizkid, Tiwa Savage.....",
img: "https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pbyam0bxypq2jrnhyzba.png",
},
{
title: "Daily Vibes 2",
content: "Lojay, Oxlade, Amaa Rae, Rema, Omah Lay, SGawd....",
img: "https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2tagaz26am1hu1gfjqze.png",
},
];
const images = [
{
img: "https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j140tnn7wsj1si27yc6q.png",
},
{
img: "https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dttp4dzeir0y4untl32p.png",
},
{
img: "https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vbv5masydlzzl02v4644.png",
},
{
img: "https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2t2relgj7l45burg2kps.png",
dot: "https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8d2zmv2d3kipklqu5ogk.png",
},
{
img: "https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9ahn4iervude9qnjzcsa.png",
},
];
return (
<AppMusicCard>
<BillboardBanner></BillboardBanner>
<Title>Welcome Back!</Title>
<SubTitle>See more</SubTitle>
<Text>Cheers to the Weekend</Text>
<SubText>See more</SubText>
<!-- looping through the array using the map function -->
{cards.map((_, index) => (
<div key={index}>
<BurnaCard src={cards[0].img} alt="" />
<BurnaTitle>{cards[0].title}</BurnaTitle>
<BurnaContent>{cards[0].content}</BurnaContent>
<LojayCard src={cards[1].img} alt="" />
<LojayTitle>{cards[1].title}</LojayTitle>
<LojayContent>{cards[0].content}</LojayContent>
<SecondBurnaCard src={cards[0].img} alt="" />
<SecondLojayCard src={cards[1].img} alt="" />
<ThirdBurnaCard src={cards[0].img} alt="" />
<ThirdBurnaTitle>{cards[0].title}</ThirdBurnaTitle>
<SecondLojayTitle>{cards[1].title}</SecondLojayTitle>
<FourthBurnaCard src={cards[0].img} alt="" />
</div>
))}
<Footer>
<FooterStyled images={images} />
</Footer>
</AppMusicCard>
);
};
export default ArtistCard;
create ArtistCard.styled.js in the styles folder:
import styled from "styled-components";
export const AppMusicCard = styled.div`
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 100%;
color: ${({ theme }) => theme.colors.text};
position: relative;
`;
export const BillboardBanner = styled.div`
background-image: url("https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uml86l79tu7y0kyed1g8.png");
position: absolute;
height: 159px;
width: 412px;
left: 0px;
top: 38px;
cursor: pointer;
`;
export const Title = styled.div`
position: absolute;
width: 155px;
left: 16px;
top: 216px;
font-style: normal;
font-weight: 700;
font-size: 20px;
line-height: 24px;
color: #ffffff;
`;
export const SubTitle = styled.div`
position: absolute;
right: 16px;
top: 245px;
font-size: 12px;
font-weight: 400;
line-height: 14px;
letter-spacing: 0.04em;
text-align: left;
color: #d9d9d9e5;
cursor: pointer;
`;
export const Text = styled.div`
height: 17px;
width: 167px;
position: absolute;
left: 15px;
top: 536px;
font-size: 14px;
font-weight: 700;
line-height: 17px;
letter-spacing: 0em;
text-align: left;
color: ${({ theme }) => theme.colors.text};
`;
export const SubText = styled.div`
position: absolute;
right: 16px;
top: 536px;
font-size: 12px;
font-weight: 400;
line-height: 14px;
letter-spacing: 0.04em;
text-align: left;
color: #d9d9d9e5;
cursor: pointer;
`;
export const BurnaCard = styled.img`
height: 228.0465545654297px;
width: 181.1341094970703px;
position: absolute;
top: 278px;
left: 15px;
cursor: pointer;
`;
export const BurnaTitle = styled.p`
position: absolute;
left: 33px;
top: 444px;
width: 121px;
font-size: 14px;
font-weight: 700;
line-height: 17px;
letter-spacing: 0.04em;
text-align: left;
color: #ffffff;
`;
export const BurnaContent = styled.p`
height: 21.603561401367188px;
width: 142.42347717285156px;
position: absolute;
left: 35px;
top: 467px;
font-size: 8px;
font-weight: 500;
line-height: 10px;
letter-spacing: 0.04em;
text-align: left;
`;
export const LojayCard = styled.img`
height: 228.0465545654297px;
width: 181.1341094970703px;
position: absolute;
top: 278px;
right: 30.87px;
cursor: pointer;
`;
export const LojayTitle = styled.p`
position: absolute;
left: 233px;
top: 444px;
width: 121px;
font-size: 14px;
font-weight: 700;
line-height: 17px;
letter-spacing: 0.04em;
text-align: left;
color: #ffffff;
`;
export const LojayContent = styled.p`
height: 21.603561401367188px;
width: 142.42347717285156px;
position: absolute;
left: 233px;
top: 467px;
font-size: 8px;
font-weight: 500;
line-height: 10px;
letter-spacing: 0.04em;
text-align: left;
`;
export const SecondBurnaCard = styled.img`
height: 228.0465545654297px;
width: 181.1341094970703px;
position: absolute;
top: 279px;
left: 410px;
cursor: pointer;
`;
export const SecondLojayCard = styled.img`
height: 228.0465545654297px;
width: 181.1341094970703px;
position: absolute;
top: 570px;
right: 30.87px;
cursor: pointer;
`;
export const ThirdBurnaCard = styled.img`
height: 228.0465545654297px;
width: 181.1341094970703px;
position: absolute;
top: 570px;
left: 15px;
cursor: pointer;
`;
export const ThirdBurnaTitle = styled.p`
position: absolute;
left: 33px;
top: 736px;
width: 121px;
font-size: 14px;
font-weight: 700;
line-height: 17px;
letter-spacing: 0.04em;
text-align: left;
color: #ffffff;
z-index: 1;
`;
export const SecondLojayTitle = styled.p`
position: absolute;
left: 233px;
top: 736px;
width: 121px;
font-size: 14px;
font-weight: 700;
line-height: 17px;
letter-spacing: 0.04em;
text-align: left;
color: #ffffff;
z-index: 1;
`;
export const FourthBurnaCard = styled.img`
height: 228.0465545654297px;
width: 181.1341094970703px;
position: absolute;
top: 570px;
left: 410px;
cursor: pointer;
`;
//Footer Styles
export const Footer = styled.div`
position: absolute;
height: 92px;
width: 428px;
left: 0px;
top: 751px;
z-index: 1;
background-color: ${({ theme }) => theme.colors.header};
`;
export const HomeIcon = styled.img`
width: 25.155181884765625px;
height: 29.4px;
left: 44px;
top: 871px;
cursor: pointer;
position: absolute;
top: 37px;
left: 44px;
z-index: 1;
`;
export const EyeIcon = styled.img`
width: 34.26810836791992px;
position: absolute;
top: 37px;
left: 144px;
cursor: pointer;
`;
export const LibraryIcon = styled.img`
position: absolute;
height: 28px;
width: 28px;
left: 253px;
top: 37px;
cursor: pointer;
`;
export const PlaylistIcon = styled.img`
position: absolute;
height: 28px;
width: 28px;
left: 356px;
top: 37px;
cursor: pointer;
`;
export const PlaylistDot = styled.img`
width: 6.25px;
position: absolute;
left: 362.25px;
top: 55.06px;
cursor: pointer;
`;
export const FirstDrumIcon = styled.img`
height: 85.95px;
position: absolute;
left: 0px;
top: 5.21px;
cursor: pointer;
object-fit: contain;
`;
export const SecondDrumIcon = styled.img`
height: 85.95px;
position: absolute;
left: 108.88px;
top: 3.41px;
cursor: pointer;
z-index: -1;
`;
export const ThirdDrumIcon = styled.img`
height: 85.95px;
position: absolute;
left: 213.33px;
top: 1.46px;
cursor: pointer;
z-index: -1;
`;
export const FourthDrumIcon = styled.img`
height: 85.95px;
position: absolute;
left: 320px;
top: 1.46px;
cursor: pointer;
`;
create a footer file in the component folder and add:
import React from "react";
import {
EyeIcon,
FirstDrumIcon,
FourthDrumIcon,
HomeIcon,
LibraryIcon,
PlaylistDot,
PlaylistIcon,
SecondDrumIcon,
ThirdDrumIcon,
} from "./styles/ArtistCard.styled";
const FooterStyled = ({ images }) => {
return (
<>
{images.map((_, index) => (
<div key={index}>
<HomeIcon src={images[0].img} alt="" />
<EyeIcon src={images[1].img} alt="" />
<LibraryIcon src={images[2].img} alt="" />
<PlaylistIcon src={images[3].img} alt="" />
<PlaylistDot src={images[3].dot} alt="" />
<FirstDrumIcon src={images[4].img} alt="" />
<SecondDrumIcon src={images[4].img} alt="" />
<ThirdDrumIcon src={images[4].img} alt="" />
<FourthDrumIcon src={images[4].img} alt="" />
</div>
))}
</>
);
};
export default FooterStyled;
Top comments (1)
Great article, you got my follow, keep writing!