Inline styles

The official React documentation suggests developers use inline styles to style their React components. This seems odd because we all learned in past years that separating the concerns is important and we should not mix markup and CSS.

React tries to change the concept of separation of concerns by moving it from the separation of technologies to the separation of components. Separating markup, styling, and logic into different files when they are tightly coupled and where one cannot work without the other is just an illusion. Even if it helps keep the project structure cleaner, it does not give any real benefit.

In React, we compose components to create applications where components are a fundamental unit of our structure. We should be able to move components across the application, and they should provide the same result regarding both logic and UI, no matter where they get rendered.

This is one of the reasons why collocating the styles within our components and applying them using inline styles on the elements could make sense in React.

First, let's look at an example of what it means to use the style attribute of the nodes to apply the styling to our components in React.

We are going to create a button with the text Click me!, and we are going to apply a color and a background color to it:

  const style = { 
color: 'palevioletred',
backgroundColor: 'papayawhip'
};

const Button = () => <button style={style}>Click me!</button>;

As you can see, it is pretty easy to style elements with inline styles in React. We just have to create an object where the attributes are the CSS rules, and the values are the values we would use in a regular CSS file.

The only differences are that the hyphenated CSS rules must be camelCased to be JavaScript-compliant, and the values are strings, so they have to be wrapped in quote marks.

There are some exceptions regarding the vendor prefixes. For example, if we want to define a transition on webkit, we should use the WebkitTransition attribute, where the webkit prefix begins with a capital letter. This rule applies to all the vendor prefixes, except for ms, which is lowercase.

Other use cases are numbers—they can be written without quotes or units of measurement and, by default, they are treated as pixels.

The following rule applies a height of 100 px:

  const style = { 
height: 100
};

By using inline styles works, we can also do things that are hard to implement with regular CSS. For example, we can recalculate some CSS values on the client at runtime, which is a very powerful concept, as you will see in the following example.

Suppose you want to create a form field in which the font size changes according to its value. So, if the value of the field is 24, the font size is going to be 24 pixels. With normal CSS, this behavior is almost impossible to reproduce without putting in a huge effort and duplicated code.

Let's look at how easy it is to use inline styles instead.

We create a class because we have to store the state, and we need an event handler:

  class FontSize extends Component {

}

The class has a constructor, where we set the default value for the state, and we bind the handleChange handler, which listens to the onChange event of the input field:

  constructor(props) { 
super(props);

this.state = {
value: 16
};

this.handleChange = this.handleChange.bind(this);
}

We implement a simple change handler, where we use the target attribute of the event to retrieve the current value of the field:

  handleChange({ target: { value } }) { 
this.setState({
value: Number(value)
});
}

Finally, we render the input file of type number, which is a controlled component because we keep its value updated by using the state. It also has an event handler, which is fired every time the value of the field changes.

Last but not least, we use the style attribute of the field to set its font-size. As you can see, we are using the camelCased version of the CSS rule to follow the React convention:

  render() { 
return (
<input
type="number"
value={this.state.value}
onChange={this.handleChange}
style={{ fontSize: this.state.value }}
/>
);
}

Rendering the preceding component, we can see an input field, which changes its font size according to its value. The way it works is that when the value changes, we store the new value of the field inside the state. Modifying the state forces the component to re-render, and we use the new state value to set the display value of the field and its font size: it's easy and powerful.

Every solution in computer science has its downsides, and it always represents a trade-off. In the case of inline styles, unfortunately, the problems are many.

For example, with inline styles, it is not possible to use pseudo-selectors (for example, :hover) and pseudo-elements, which is a pretty significant limitation if you are creating a UI with interactions and animations.

There are some workarounds, and for example, you can always create real elements instead of pseudo ones, but for the pseudo-classes, it is necessary to use JavaScript to simulate the CSS behavior, which is not optimal.

The same applies to media queries, which cannot be defined using inline styles, and it makes it harder to create responsive web applications. Since styles are declared using JavaScript objects, it is also not possible to use style fallbacks:

  display: -webkit-flex; 
display: flex;

JavaScript objects cannot have two attributes with the same name. Style fallbacks should be avoided, but it is always good to have the ability to use them if needed.

Another feature of CSS that it is not possible to emulate using inline styles is animations. The workaround here is to define animations globally and use them inside the style attribute of the elements.

With inline styles, whenever we need to override a style with regular CSS, we are always forced to use the !important keyword, which is bad practice because it prevents any other style being applied to the element.

The most difficult thing that happens working with inline styles is debugging. We tend to use class names to find elements in the browser DevTools to debug and check which styles have been applied.

With inline styles, all the styles of the items are listed in their style attribute, which makes it very hard to check and debug the result.

For example, the button that we created earlier in this section is rendered in the following way:

  <button style="color:palevioletred;background-
color:papayawhip;">Click me!</button>

By itself, it does not seem very hard to read, but if you imagine you have hundreds of elements and hundreds of styles, you realize that the problem becomes very complicated.

Also, if you are debugging a list where every single item has the same style attribute, and if you modify one on the fly to check the result in the browser, you will see that you are applying the styles only to it and not to all the other siblings, even if they share the same style.

Last but not least, if we render our application on the server side (we will cover this topic in Chapter 8Server-Side Rendering for Fun and Profit), the size of the page is bigger when using inline styles.

With inline styles, we are putting all the content of the CSS into the markup, which adds an extra number of bytes to the file that we send to the clients and makes the web application appear slower.

Compression algorithms can help with that because they can easily compress similar patterns, and, in some cases, loading the critical path CSS is a good solution, but in general, we should try to avoid it.

It turns out that inline styles give more problems than the problems they try to solve.

For this reason, the community created different tools to solve the problems of inline styles but keeping the styles inside the components, or local to the components, to get the best of both worlds.

After Christopher Chedeau's talk, a lot of developers started talking about inline styles, and many solutions and experiments have been made to find new ways of writing CSS in JavaScript.

In the beginning, there were two or three, while today there are more than forty.

In the following sections, we will go through the most popular ones.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.221.222.47