React Gradients
Inspired by https://dribbble.com/shots/13662178-Gradients
A Pen by Marco Biedermann on CodePen.
<div id="root"></div> |
React Gradients
Inspired by https://dribbble.com/shots/13662178-Gradients
A Pen by Marco Biedermann on CodePen.
const AspectRatio = (props) => { | |
const { ratio = 1 / 1, ...otherProps } = props; | |
return ( | |
<div | |
className="aspect-ratio" | |
style={{ paddingTop: `${100 / ratio}%` }} | |
{...otherProps} | |
/> | |
); | |
}; | |
const Gradient = (props) => { | |
const { angle = 0, from, to } = props; | |
return ( | |
<div | |
style={{ | |
backgroundImage: `linear-gradient(${angle}deg, ${from}, ${to})` | |
}} | |
/> | |
); | |
}; | |
const Palette = (props) => { | |
const { from, to } = props; | |
return ( | |
<figure className="palette"> | |
<AspectRatio> | |
<Gradient angle={135} {...props} /> | |
</AspectRatio> | |
<figcaption className="palette__caption"> | |
{from} – {to} | |
</figcaption> | |
</figure> | |
); | |
}; | |
const Palettes = (props) => { | |
const { palettes } = props; | |
return ( | |
<div className="palettes"> | |
{palettes.map((palette) => ( | |
<Palette key={palette.toString()} {...palette} /> | |
))} | |
</div> | |
); | |
}; | |
const Grid = (props) => { | |
return <div className="grid" {...props} />; | |
}; | |
const App = () => { | |
const palettes = [ | |
{ | |
from: "#f40076", | |
to: "#df98fa" | |
}, | |
{ | |
from: "#f06966", | |
to: "#fad6a6" | |
}, | |
{ | |
from: "#ff0076", | |
to: "#590fb7" | |
}, | |
{ | |
from: "#9055ff", | |
to: "#13e2da" | |
}, | |
{ | |
from: "#0b63f6", | |
to: "#003cc5" | |
}, | |
{ | |
from: "#d6ff7f", | |
to: "#00b3cc" | |
}, | |
{ | |
from: "#e233ff", | |
to: "#ff6b00" | |
}, | |
{ | |
from: "#df98fa", | |
to: "#9055ff" | |
}, | |
{ | |
from: "#ed7b84", | |
to: "#9055ff" | |
}, | |
{ | |
from: "#402565", | |
to: "#30be96" | |
}, | |
{ | |
from: "#402662", | |
to: "#3900a6" | |
}, | |
{ | |
from: "#f14658", | |
to: "#dc2537" | |
}, | |
{ | |
from: "#f40076", | |
to: "#342711" | |
}, | |
{ | |
from: "#000066", | |
to: "#6699ff" | |
}, | |
{ | |
from: "#cb5eee", | |
to: "#4be1ec" | |
}, | |
{ | |
from: "#fa7cbb", | |
to: "#f14658" | |
}, | |
{ | |
from: "#737dfe", | |
to: "#ffcac9" | |
}, | |
{ | |
from: "#2f80ed", | |
to: "#b2ffda" | |
} | |
]; | |
return ( | |
<div className="app"> | |
<Grid> | |
<Palettes palettes={palettes} /> | |
</Grid> | |
</div> | |
); | |
}; | |
ReactDOM.render(<App />, document.getElementById("root")); |
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script> |
@use postcss-preset-env { | |
stage: 0; | |
} | |
:root { | |
--color-background: #e8e0fd; | |
--color-text: #111; | |
--font-family: Roboto, sans-serif; | |
} | |
body { | |
background-color: var(--color-background); | |
color: var(--color-text); | |
display: grid; | |
font-family: var(--font-family); | |
line-height: 1.5; | |
margin: 0; | |
min-block-size: 100vh; | |
place-content: center; | |
} | |
.app { | |
padding: 5vmin; | |
} | |
.grid { | |
inline-size: 90vw; | |
margin-inline: auto; | |
max-inline-size: 1440px; | |
} | |
.aspect-ratio { | |
overflow: hidden; | |
padding-block-start: 100%; | |
position: relative; | |
} | |
.aspect-ratio > * { | |
bottom: 0; | |
left: 0; | |
position: absolute; | |
right: 0; | |
top: 0; | |
} | |
.palettes { | |
display: grid; | |
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); | |
gap: 3em; | |
} | |
.palette { | |
box-shadow: 0.25em 0.25em 2em rgba(0, 0, 0, 0.25); | |
border-radius: 0.5em; | |
margin: 0; | |
overflow: hidden; | |
} | |
.palette__caption { | |
background-color: #fff; | |
font-size: 0.875rem; | |
font-weight: 500; | |
padding: 1.5em; | |
text-align: center; | |
text-transform: uppercase; | |
} |