So I decided to try to build my portfolio with StyledComponents. I’m using theme provider to implement a “dark” and “light” theme. I am having an issue with one background color on an &:after.. For some reason it is pulling the light theme version of the color regardless of the theme.
My setup looks like this.
I defined 5 variables that change between light and dark theme in theme.js.
import { createGlobalStyle } from "styled-components";
let beige = "#f6d8ae";
let blue = "#083d77";
let pink = "#da4167";
let yellow = "#f4d35e";
let gray = "#2e4057";
export const lightTheme = {
one: pink,
two: blue,
three: beige,
four: blue,
five: blue,
};
export const darkTheme = {
one: blue,
two: pink,
three: gray,
four: yellow,
five: gray,
};
export const GlobalStyles = createGlobalStyle`
.typeA{
background-color: ${(props) => props.theme.one};
color: #f4d35e;
}
.typeB{
background-color: ${(props) => props.theme.three};
color: ${(props) => props.theme.four};
}
.contact{
background-color:${(props) => props.theme.five};
}
`;
You’ll notice that ‘two’ in the light and dark theme isnt used in the classes. It’s applied directly in the component.styled sheets as follows..
import styled from "styled-components";
export const JobContainer = styled.div`
display: flex;
justify-content: center;
flex-direction: row;
position: relative;
width: 100vw;
height: 75vh;
flex-wrap: wrap;
`;
export const MainDiv = styled.div`
display: inline-flex;
margin: 25px;
margin-bottom: 90px;
`;
export const Title = styled.div`
position: relative;
width: max-content;
font-size: 28pt;
font-weight: 700;
height: max-content;
margin: 20px;
margin-bottom: 20px;
z-index: 1;
&:after {
content: "";
background-color: ${(props) => props.theme.two};
height: 12px;
display: block;
position: absolute;
width: 100%;
left: 0;
bottom: 15%;
z-index: -1;
}
`;
export const TitleB = styled.div`
position: relative;
width: max-content;
font-size: 28pt;
font-weight: 700;
height: max-content;
margin: 20px;
margin-bottom: 20px;
z-index: 1;
&:after {
content: "";
background-color: ${(props) => props.theme.two};
height: 12px;
display: block;
position: absolute;
width: 100%;
left: 0;
bottom: 15%;
z-index: -1;
}
`;
So the background color on the pseudo element will be the color specified for ‘two’ in the light theme. Maybe it has something to do with the way Im providing themeprovider or globalstyles in the components? The variable works fine in one of the components which is set up like this…
import React, { useState } from "react";
import {
MainContainer,
Intro,
Line,
LineBox,
IntroBox,
Image,
} from "./styles/Home.Styled";
import { ThemeProvider } from "styled-components";
import { lightTheme, darkTheme, GlobalStyles } from "../themes.js";
import { Birds } from "../components/Birds";
export function Home() {
const [theme, setTheme] = useState("light");
const themeToggler = () => {
console.log("holla", theme);
theme === "light" ? setTheme("dark") : setTheme("light");
};
return (
<>
<ThemeProvider theme={theme === "light" ? lightTheme : darkTheme}>
<GlobalStyles />
<MainContainer className="typeA" onClick={() => themeToggler()}>
<Birds />
<IntroBox>
<Intro>
<Line>Hello World.</Line>
</Intro>
<LineBox>
<Line>My Name is Dale.</Line>
</LineBox>
</IntroBox>
</MainContainer>
</ThemeProvider>
</>
);
}
The onClick in that component controls the theme for the whole page.
And finally, the component where the variable is not working..
import React, { useState } from "react";
import { ThemeProvider } from "styled-components";
import { lightTheme, darkTheme, GlobalStyles } from "../themes.js";
import {
JobContainer,
JobContainerB,
Card,
Title,
TitleB,
Image,
Blurb,
TitleDiv,
ImageDiv,
WordDiv,
MainDiv,
} from "./styles/Projects.Styled";
import heycouldyou from "../assets/projectScreenshots/heycouldyou.png";
import nyet from "../assets/projectScreenshots/nyet.png";
import shoulda from "../assets/projectScreenshots/shoulda.png";
export function Projects() {
const [theme, setTheme] = useState("light");
const themeToggler = () => {
theme === "light" ? setTheme("dark") : setTheme("light");
};
return (
<>
<ThemeProvider theme={theme === "light" ? lightTheme : darkTheme}>
<JobContainer className="typeA">
......
</JobContainer>
<JobContainer className="typeB">
......
</JobContainer>
<JobContainer className="typeA">
......
</JobContainer>
</ThemeProvider>
</>
);
}
Im sure I could find a workaround but I want to make sure I understand why it’s not working like I am expecting. Thanks for taking the time to read this, even more for any help you may be able to provide!