diehell diehell - 3 months ago 74
React JSX Question

Beginner: Styling ReactJS Checkbox using CSS Pseudo Elements

I am trying to style reactjs checkbox component using CSS. It uses pseudo-elements :after and :before.

Mock it up on html and css and it worked! Fiddle Link

input[type="checkbox"]#checkbox + label::before {
content: "";
display: inline-block;
vertical-align: -25%;
height: 2ex;
width: 2ex;
background-color: white;
border: 1px solid #c3c4c6;
border-radius: 4px;
margin-right: 0.5em;
}

input[type="checkbox"]#checkbox:checked + label::after {
content: '';
position: absolute;
width: 1.2ex;
height: 0.4ex;
background: rgba(0, 0, 0, 0);
top: 0.5ex;
left: 0.4ex;
border: 3px solid #60cd18;
border-top: none;
border-right: none;
-webkit-transform: rotate(-45deg);
-moz-transform: rotate(-45deg);
-o-transform: rotate(-45deg);
-ms-transform: rotate(-45deg);
transform: rotate(-45deg);
}


But when i tried to implement it on my reactjs component that display checkbox,maybe the :after doesn't work. Fiddle ReactJS Component Link

How should i achieve the same style on ReactJS checkbox component?

Answer

There's couple of ways to use pseudo elements on React such as Radium, but afaik it doesn't support :after/:before, instead according to this and this, it suggest creating an element in place of the pseudo-elements. I didn't find any React example of this and i think the availability of pseudo elements was to avoid creating unnecessary DOM elements.

With all that limitations, my current solution for customising the checkbox in react so that it works on most browsers was to create an element that acts,looks, and feel like a checkbox(imposter), but not a checkbox by itself (input type="checkbox"). I achieved this by using ReactJS to trigger the visibility of the span element and font-awesome icon.

Example

/*  html   */
<div id="container">
</div>

/* JS  */
var Checkbox = React.createClass({
        getDefaultProps: function() {
        return {
        value: true,
        name: '',
        borderWidth: '1px',
        borderStyle: 'solid',
        borderColor: '#c3c4c6',
        borderRadius: '4px',
        checkColor: '#60cd18',
        height: '1px',
        width: '',
        namePaddingLeft: '10px',
        namePaddingRight: ''
        };
    },
    render: function() {
        var style = {
            boxStyle: {
            borderWidth: this.props.borderWidth,
            borderStyle: this.props.borderStyle,
            borderColor: this.props.borderColor,
            borderRadius: this.props.borderRadius,
            paddingLeft: this.props.width,
                    paddingRight: this.props.width,
            paddingTop: this.props.height,
            paddingBottom: this.props.height
          },
          show: {
            visibility: 'visible',
            color: this.props.checkColor
          },
          hidden: {
            visibility: 'hidden',
            color: this.props.checkColor
          },
          name: {
            paddingLeft: this.props.namePaddingLeft,
            paddingRight: this.props.namePaddingRight
          }
        };
        return (
        <div>
            <span style={style.boxStyle}>
                    <i className="fa fa-check fa-lg" style={(this.props.value) ? style.show : style.hidden}></i>
                    </span>
           <span style={style.name}>{this.props.name}</span>
        </div>
        );
    }
});

var WrapperCheckbox = React.createClass({ 
    getInitialState: function(){
    return {value: false}
  },
  handleClick: function(){
    console.log('Click Fires!');
    this.setState({value: !this.state.value});
  },
    render: function(){
    return (
        <div onClick={this.handleClick}>
            <Checkbox name='Reserve Guarantee' value={this.state.value}/>
      </div>
    );
  }
});

React.render(<WrapperCheckbox />, document.getElementById('container'));