Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62
Subscribe to my email list now at http://jauyeung.net/subscribe/
React is the most used front end library for building modern, interactive front end web apps. It can also be used to build mobile apps.
In this article, we’ll look at creating styled-components with pseudo selectors and creating styled wrappers for other components.
Define Styled Components Outside of the Render Method
We can define styled-components outside of the render method with styled-components
.
For instance, we can define a wrapper component as follows:
import React from "react";
import styled from "styled-components";
const StyledWrapper = styled.div`
font-weight: bold;
`;
const Wrapper = ({ message }) => {
return <StyledWrapper>{message}</StyledWrapper>;
};
export default function App() {
return (
<div className="App">
<Wrapper message="foo" />
</div>
);
}
In the code above, we created the StyledWrapper
component with its own styles. Then we created the Wrapper
component which uses it. with the message
prop passed inside. Then we can ass message
as a prop to Wrapper
used in App
.
Therefore, we’ll see the word ‘foo’ bolded displayed on the screen.
Pseudoelements, Pseudoselectors, and Nesting
styled-components
supports SCSS-like syntax for defining styles for a styled component. The preprocessor that uses for transforming CSS is stylis.
For instance, we can write the following code to define styles with props and stylis code as follows:
import React from "react";
import styled from "styled-components";
const Thing = styled.div.attrs(() => ({ tabIndex: 0 }))`
color: blue;
&:hover {
color: red;
}
& ~ & {
background: tomato;
}
& + & {
background: lime;
}
&.foo {
background: orange;
}
.foo & {
border: 1px solid ${props => (props.primary ? "red" : "green")};
}
`;
export default function App() {
return (
<div className="App">
<Thing>foo</Thing>
<Thing className="foo" primary>
<Thing>abc</Thing>
<Thing primary>abc</Thing>
bar
</Thing>
<Thing className="bar">baz</Thing>
<Thing>baz</Thing>
</div>
);
}
In the code above, we have the Thing
component, where we defined styles with pseudo selectors.
&:hover
is the selector for when Thing
is hovered.
& ~ &
is the selector for the sibling of Thing
but it may not be directly next to it.
& + &
is the Thing
next to a Thing
.
&.foo
is the Thing
with a foo
CSS class.
.foo &
is the Thing
inside something with the foo
class. We also have a dynamic style with ${props => (props.primary ? “red” : “green”)}
where we check for the primary
prop and then apply the color accordingly.
Then we get the following colored text:
We can add the &&
pseudoselector to increase the specificity of the rules on the component.
For instance, we can write:
import React from "react";
import styled from "styled-components";
const Thing = styled.div`
&& {
color: blue;
}
`;
export default function App() {
return (
<div className="App">
<Thing>foo</Thing>
</div>
);
}
Then we only apply the specified style to Thing
. Therefore, we avoid conflicts with styles in other components with &&
.
Photo by Pineapple Supply Co. on Unsplash
Attaching Additional Props
We can pass in a callback to the attrs
method so that we can choose the props that the base element receives. For instance, if we have an input and we want it to only receive the value
attribute and the size
prop, we can write:
import React from "react";
import styled from "styled-components";
const Input = styled.input.attrs(({ value, size }) => ({
size,
value
}))`
color: palevioletred;
font-size: 1em;
margin: ${props => props.size};
padding: ${props => props.size};
`;
export default function App() {
return (
<div className="App">
<Input value="foo" size="5px" />
</div>
);
}
In the code above, we took the value
andsize
props and set them as attributes in the callback that we pass into the attrs
method.
We also passed in the size
prop into our styles dynamically in the string.
Then when we add the Input
with the value
set to 'foo'
and size
set to '5px'
, then we’ll see those reflected in our styled input.
Conclusion
We can create styled components that are outside of the render method. Also, in addition to CSS selectors, we can use SCSS selectors for selecting elements.
The &
selector is useful for selecting the current element. We can then use other selectors to select neighboring or child elements.
Also, we can use the &&
selector to select one specific element.
Finally, we can use the attrs
method to selectively pass props as attribute values of components.