1

I trying to style a React component so that the individual elements can either be styled horizontally or vertically (with a non-flexbox solution).

How can I pass down styles to the component where individual styles are to be applied to the child elements of the component?

e.g. To produce horizontal

and

vertical

Where the styles only relevant for the horizontal are:

input, button {
    vertical-align:middle;
}

button {
    margin-left: 10px;
}

and only relevant for the vertical layout are:

.form-control {
    display: inline-block;
}

.btn {
    display:  block;
    margin: auto;
}

and the component is:

class Form extends React.Component {

  render () {
    return (
      <form className="form-group">
        <input className="form-control" type="text" placeholder="St. George, Utah"/>
        <button className="btn">Get Weather</button>
      </form>
    );
  }
}
1
  • You can pass a boolean prop to determine if it should be horizontal or not, and toggle "in-line" styles in your javascript on the button component itself. Commented May 31, 2017 at 19:50

1 Answer 1

1

There are a couple of ways to approach this.

The first one, and more controlled one has to do with Michael Lyons' commend. Pass a prop down to the component that determines whether or not the component layout is vertical or horizontal.

When you receive that variable, you can add classes to your component to style it as you desire.

Your component can look like this:

class Form extends React.Component {

  render () {
    let buttonClassName = "btn" + (this.props.isVertical)? " vertical-button" : "horizontal-button";
    let inputClassName = "form-control" + (this.props.isVertical)? " vertical-input": "hotizontal-input";
    return (
      <form className="form-group" >
        <input className={inputClassName} type="text" placeholder="St. George, Utah"/>
        <button className={buttonClassName} >Get Weather</button>
      </form>
    );
  }
} 

Your CSS can look something like this:

/* For the vertical form */

.vertical-input {
    display: inline-block;
}

.vertical-button {
    display:  block;
    margin: auto;
}

/* For the horizontal form */

.horizontal-input, .horizontal-button {
    vertical-align:middle;
}

.horizontal-button {
    margin-left: 10px;
}

Alternatively, you can pass a style object to the style attribute of the HTML tags directly depending on which flag you receive. Say, if you receive this.props.isVertical you create a JS object that would like like this:

let inputStyle = { display: "inline-block" };

And pass it t the tag like so:

<input className="form-control" type="text" style={inputStyle} placeholder="St. George, Utah" />

Quick note: the keys on the object that you pass to the HTML tag need to be camelCased instead of separated by dashed. So, margin-left becomes marginLeft.

Sign up to request clarification or add additional context in comments.

1 Comment

I'd err on the side of the class solution for the sake of being able to over-ride in the future, inline styles are very specific and can only be over-ridden by !important

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.