Reputation: 309
I'm trying to build a React component that shows multiple images stored in a database, where below each thumbnail image there is a button linking to its dedicated page. Now, I would like each button to show the dominant color of the image as background on hover. I already have the colors stored in database (artwork.palette.DOMINANT
), but struggles to pass the hex code to the React component.
The problem is, inline style cannot set properties of pseudo selectors like a:hover
, and because the color is dynamically fetched with the artwork
object, I can not set it in a global and static css. Is there a way to set component-scoped style in React? Presumably like <style scoped>...</style>
.
Here is my code, I only kept the gist of it for simplicity's sake.
const ImageBox = ({ artwork }) => {
return (
<Fragment>
<div className="image">
<img src={artwork.resources.THUMBNAIL} alt={artwork.title} />
</div>
<div className="caption">
<span>By {artwork.artist}.</span>
</div>
<div className="button">
<a href="!#" style={{ color: artwork.palette.DOMINANT }}>
Details
</a>
</div>
</Fragment>
);
};
Upvotes: 6
Views: 2687
Reputation: 4723
I was looking for how to set styles dynamically. My main intention was to write a style for hover. Using state to track whether it is hovered or not is good but that will cost render for each update. So I thought How I can solve it with out any state change. I end up doing this and it works perfectly.
<a
target='_blank'
href="#"
onMouseOver={(e) => e.target.style.color = 'red'}
onMouseOut={(e) => e.target.style.color = ''}
>
This is my link
</a>
Upvotes: 2
Reputation: 309
Thanks to @PramodMali, I found the CSS-in-JS approach as a elegant way to solve this problem. For anyone who stumbles upon the same struggle in the future, here's how I solved it with react-css
:
import { createUseStyles } from "react-jss";
const useStyles = (dominantColor = "#fff") =>
createUseStyles({
toDetailPage: {
color: dominantColor,
"&:hover": {
color: "#000",
background: dominantColor,
}
}
});
After defining the style generator, use it to dynamically set classes in component:
const ImageBox = ({ artwork }) => {
const classes = useStyles(artwork.palette.dominant)();
return (
<Fragment>
<div className="image">
<img src={artwork.resources.THUMBNAIL} alt={artwork.title} />
</div>
<div className="caption">
<span>By {artwork.artist}.</span>
</div>
<div className="button">
<a href="!#" className={classes.toDetailPage}>
Details
</a>
</div>
</Fragment>
);
};
This will then generate dynamic classes on render, for instance detailsButton-0-2-7
, which applies the properties passed to the generator function when defining classes
.
Upvotes: 3
Reputation: 1798
You could use JS to modify the global properties of CSS.
index.css
or App.css
and add your basic styles that will utilize these variables.:root {
--color-surface: white;
}
button {
background: var(--color-surface);
}
onMouseEnter
and onMouseLeave
). i.e.//onMouseEnter
document.documentElement.style.setProperty("--color-surface", "black");
//onMouseLeave
document.documentElement.style.setProperty("--color-surface", "white")
There a few references you can follow:
Blog and CodSandBox
Note: Not sure if it's a good practice(I haven't seen in projects I've worked on), I would recommend using CSS-in-JS or libraries such as styled component.
Upvotes: 4