22

I have a React component called "ExplanationLists", I would like to add dynamic inline style into li html element with css pseudo code li::after, the way I can style the bullet-point with graphic better. For example,

li::before {
    content: dynamic_content;
}

However, I couldn't really make it happen. Any suggestion would be appreciated.

Below is the code I've written.

class ExplanationLists extends Component{
    populateHtml(){
        // asign lists data into variable "items"
        var items = this.props.items; 

        // loop though items and pass dynamic style into li element
        const html = items.map(function(item){
            var divStyle = {
                display: "list-item",
                listStyleImage: 
                    'url(' +  
                    '/images/icons/batchfield_fotograf_rosenheim_icon_' + 
                    item.icon +
                    '.png' +
                    ')'   
            };  

            // html templating 
            return (
                 <li style={divStyle}>
                   <h3 >{item.title}</h3>
                   <p>{item.desc}</p>
                 </li>
            );
        });

        // return html
        return html;
    }

    render(){
        return (
            <ul>
                {this.populateHtml()}
            </ul>
        )
    }
}
nondestructive
  • 134
  • 2
  • 10
Chun Pin Chen
  • 433
  • 1
  • 3
  • 11
  • Why don't you just simple use `className` at your `li` element, then styling it with normal CSS ? – An Nguyen Aug 17 '17 at 08:45
  • 3
    Because it's dynamic content, not the same thing every time. Needs to be set via javascript. – stone Aug 22 '19 at 22:07

4 Answers4

20

In your particular case you can use data attributes.

li::before {
  content: attr(data-content);
}
render = () => <li data-content={this.props.content}>{this.props.children}</li>
Qwerty
  • 29,062
  • 22
  • 108
  • 136
  • 1
    Super cool. 8 Years in web dev and I just knew this. Thanks mate – idiglove Feb 25 '23 at 20:27
  • Hey @idiglove that is so relatable, I learned that myself 5 minutes before posting that answer , though it took me possibly an hour of investigation – Qwerty Apr 26 '23 at 18:56
  • Note: attr() evaluates to string. You can't evaluate #ffffff or some other colour to hex like background-color: attr(data-content); – Satbir Kira May 24 '23 at 19:25
  • @SatbirKira Yes, only `content` in `::before` and `::after` is now officially supported. More is in the works https://developer.mozilla.org/en-US/docs/Web/CSS/attr – Qwerty May 24 '23 at 21:10
5

No, it's not possible. React style attribute use the HTML style attribute underlyingly, so it cannot have selectors inside it. Like stated in this answer about inline style.

The value of the style attribute must match the syntax of the contents of a CSS declaration block (excluding the delimiting braces), whose formal grammar is given below in the terms and conventions of the CSS core grammar:

declaration-list
  : S* declaration? [ ';' S* declaration? ]*
  ;
Tr1et
  • 873
  • 11
  • 25
4
  1. "&::before": { ...react style here }
  2. you must have attribute content: `''`

example:


        content: {
            display: "flex",
            margin: 10,
            "&::before": {
                content: `''`,
                position: 'absolute',
                left: '-50px',
                top: '50px',
                width: '0',
                height: '0',
                border: '50px solid transparent',
                borderTopColor: 'red',
            }
        },

Hope this helps!

Niels Steenbeek
  • 4,692
  • 2
  • 41
  • 50
nokieng
  • 1,858
  • 20
  • 24
  • 19
    The question doesn't mention `glamorous` library, so your answer is misleading.. – Karolis.sh Oct 20 '19 at 08:44
  • 1
    @KarolisŠarapnickis Sorry that I did not notice the library name, I was able to do like above by creating the app with facebook create-react-app command without any other related library as I remember. – nokieng Nov 11 '19 at 07:17
-4

React does not have CSS pseudo-elements. The idea is to solve in Javascript way. Put it simply, add a span before or after the DOM element. I find it quite nice, more powerful than CSS. Take a look at a-theme-react I built for example

const beforeImg = (
    <img
        src={screenshot5}
        style={{
            width: '216px',
            marginTop: '87px',
            marginLeft: '79px',
            height: '393px'
        }}
    />
)

export const FormSection = {
    margin: '0 0 10px',
    color: '#262626',
    backgroundColor: '#fff',
    border: '1px solid #e6e6e6',
    borderRadius: '1px',
    textAlign: 'center',
    width: '350px',
    display: 'inline-block',
    verticalAlign: 'middle',
    before: {
        content: beforeImg,
        display: 'inline-block',
        width: '400px',
        height: '560px',
        verticalAlign: 'middle',
        backgroundImage: 'url(' + home_phone + ')',
        backgroundSize: '400px 560px'
    }
}

Then in render method look for .before attribute, render content with styles.

Richard Zhang
  • 350
  • 1
  • 4