I am trying to refactor some css to use styled components so I can just deploy the cloud component and declare its size styles and what animation styles it uses through props so it looks like this:
<Cloud size={TinyCloud} animation={cloud_1}/>
I have a base style to define a cloud:
const Cloud = styled(css)`
-webkit-animation: clouds 60s infinite linear;
-moz-animation: clouds 60s infinite linear;
-ms-animation: clouds 60s infinite linear;
-o-animation: clouds 60s infinite linear;
animation: clouds 60s infinite linear;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
border-radius: 10px;
position: relative;
margin: 20px 20px 10px 2050px;
width: 54px;
height: 5px;
background: black;
& div {
-moz-box-shadow: inset -2px -3px 0 0 #f7e7eb;
-webkit-box-shadow: inset -2px -3px 0 0 #f7e7eb;
box-shadow: inset -2px -3px 0 0 #f7e7eb;
position: absolute;
border-radius: 50%;
width: 12px;
height: 12px;
left: -3px;
bottom: 0;
background: #fafbf0;
z-index: 10;
}
& div:first-child + div {
-moz-transform: scale(1.6, 1.6);
-ms-transform: scale(1.6, 1.6);
-webkit-transform: scale(1.6, 1.6);
transform: scale(1.6, 1.6);
margin: 0 0 4px 13px;
z-index: 9;
}
& div:first-child + div + div {
-moz-transform: scale(2.4, 2.4);
-ms-transform: scale(2.4, 2.4);
-webkit-transform: scale(2.4, 2.4);
transform: scale(2.4, 2.4);
margin: 0 0 9px 32px;
z-index: 8;
}
& div:first-child + div + div + div {
-moz-transform: scale(1.3, 1.3);
-ms-transform: scale(1.3, 1.3);
-webkit-transform: scale(1.3, 1.3);
transform: scale(1.3, 1.3);
margin: 0 0 2px 50px;
z-index: 7;
}
@-webkit-keyframes clouds {
0% {
left: -50%;
}
100% {
left: 20%;
}
}
@-moz-keyframes clouds {
0% {
left: -50%;
}
100% {
left: 20%;
}
}
@-ms-keyframes clouds {
0% {
left: -50%;
}
100% {
left: 20%;
}
}
@keyframes clouds {
0% {
left: -50%;
}
100% {
left: 20%;
}
}
`;
This style is then extended by four more styles as such:
const TinyCloud = styled(Cloud)`
-moz-transform: scale(0.35);
-ms-transform: scale(0.35);
-webkit-transform: scale(0.35);
transform: scale(0.35);
`;
I also have 12 more styles to extend the now styled base Cloud (Now TinyCloud) as such:
const cloud_1 = styled(css)`
-webkit-animation-duration: 10s;
-moz-animation-duration: 10s;
-ms-animation-duration: 10s;
-o-animation-duration: 10s;
animation-duration: 10s;
margin-left: 40%;
`;
The sizes and animations are in separate files and exported so they can be passed as props.
What I tried was defined like this (I realize that I cannot do this but I include this to show my thinking):
const Cloud = (size, animation) => {
const CloudFrame = styled(size)`
${animation}
`
return (
<CloudFrame>
<div></div>
<div></div>
<div></div>
<div></div>
</CloudFrame>
)
};
Instead of using classes like this:
<div class="cloud tiny cloud-4">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
With styled-components, the usual per-instance customization uses adaptation based on props.
Unless your sizes and cloud id customizations are more complex than your samples, you could use this adaptation technique easily:
const CloudFrame = styled.div`
animation: clouds 60s infinite linear;
// etc.
transform: scale(${props => props.scale});
animation-duration: ${props => props.duration};
margin-left: ${props => props.left};
`;
// Usage
function App() {
return (
<CloudFrame scale={0.35} duration="10s" left="40%">
<div></div>
<div></div>
<div></div>
<div></div>
</CloudFrame>
)
}
With this, you do not even need to predefine hard coded sets of sizes and cloud ids: you can define those values arbitrarily when you instantiate the component.