Title: Efficient method of importing values from React to CSS
Tags: javascript;css;reactjs
Question: I've been looking at some different options for a method of sharing/importing values from a React component to a Sass/CSS file. I have the background property of a component being set after receiving props that contain a path to an image (from an API). This is set as an inline style.
I also want to add an opaque layer to the component image on hover. This is easily accomplished with regular CSS, however I can't simply overwrite the background property to a gradient or color when hovered over.
I need to also fetch the image path being used in the component's inline style in order to apply the opacity over the image.
Component:
render() {
const styles = {
background: `url('...somepath.jpeg') no-repeat center`
const item = { ...type, ...this.props.metadata };
return (
<section className="card"
onClick={this.props.cb.bind(null, item)}
style={styles}&gt;
</section&gt;
);
Styles:
.card:hover {
cursor: pointer;
background: linear-gradient(rgba(20,20,20, .5), rgba(20,20,20, .5)) !important;
// without the path to build the url, this just deletes the image
Basically the style I'm looking to apply on hover would appear like this:
linear-gradient(rgba(20,20,20, .5), rgba(20,20,20, .5)), url('...somepath.jpeg') no-repeat center
Is there an efficient method to accomplish something like this? I could only think of adding mouseover/mouseout event listeners to the component to add "hover" inline styles... but I want to stay way from using inline too much.
Comment: Why cannot `css` be utilized?

Comment: You can set a `css` rule at an existing `CSSStyleSheet` or append `css` text to a `` element in `document`.

Comment: @guest271314 The path to the image is coming from an API call who's response is being passed down as props to this card component. I can't find a way to import that path into a CSS file. Inline styles don't support pseudo-selectors either.

Here is the accepted answer: This is a perfect use case for styled-components. With styled components you can pass down a url as a prop, while still being able to use the full power of CSS.
Sample code specific to your case:
const Section = styled.section`
&amp;:hover {
cursor: pointer;
${(props) =&gt; `background: url(${props.url}) no-repeat center` }
render() {
const item = { ...type, ...this.props.metadata };
return (
<Secion className="card"
onClick={this.props.cb.bind(null, item)}
url="...somepath.jpeg"
/&gt;
Comment for this answer: Thanks. That's an interesting solution to the problem. However, are you ever concerned that this library is basically more inline styling? I've been told to avoid using inline styles when possible (although I can't say for sure why that may be).
Comment for this answer: This is pretty cool. What about concerns over maintaining styles inside React components **and** stylesheets? Wouldn't that scatter styling even more amid different files?
Comment for this answer: @Jose this library has almost all functionality that is available through SASS (pseudo classes, media queries, etc.). It's definitely different from plain inline styles.
Comment for this answer: @Jose in theory you should keep all your styles inside the component and have very few global styles.


{'source': 'StackExchangeDataset', 'subset': 'stackoverflow.com', 'metadata': {'AnswerCount': 1, 'CommentCount': 3, 'ContentLicense': 'CC BY-SA 3.0', 'CreationDate': '2017:00:05/13/17', 'FavoriteCount': 1.0, 'PostTypeId': 1, 'Tags': '<javascript><css><reactjs>', 'Title': 'Efficient method of importing values from React to CSS', 'ViewCount': 61, 'id': 43948793, 'user_AboutMe': None, 'user_AccountId': 5865262.0, 'user_DisplayName': 'Jose', 'user_Reputation': 4510.0, 'user_Views': 307.0, 'user_id': 4619447.0}}