📜 ⬆️ ⬇️

Styling React components

image


Introduction


There are many approaches to stylize React components, and in this article some of them will be discussed. But, for a start, we will determine the key points on which the story is based:



<!doctype html> <!--[if lt IE 7]> <html class="ie6 oldie"> <![endif]--> <!--[if IE 7]> <html class="ie7 oldie"> <![endif]--> <!--[if IE 8]> <html class="ie8 oldie"> <![endif]--> <!--[if gt IE 8]><!--> <html class=""> <!--<![endif]--> 


 background: #1e5799; /* Old browsers */ background: -moz-linear-gradient(top, #1e5799 0%, #7db9e8 100%); /* FF3.6-15 */ background: -webkit-linear-gradient(top, #1e5799 0%,#7db9e8 100%); /* Chrome10-25,Safari5.1-6 */ background: linear-gradient(to bottom, #1e5799 0%,#7db9e8 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#1e5799', endColorstr='#7db9e8',GradientType=0 ); /* IE6-9 */ 


About styling homelements


React components are rendered in real HTML, i.e. in homelements. There are two ways to customize the display of a DOMElement:


  1. External CSS styles (the style tag in the page layout, or the connection of the style file via the link tag).
  2. Internal (inline) styles (style attribute).

The second approach has many drawbacks:



Some of these shortcomings can be compensated by combining the 2nd approach with the 1st, but not all.


Pro Facebook policy


It is known that Facebook, as a developer of React, despite the shortcomings described above still promotes the use of Inline Styles . They can be understood, they strive to provide a uniform approach with React Native , because there only Inline Styles are available. But this is not easier for us, because Facebook doesn’t offer anything sensible to Facebook itself in terms of styling React components. But there were many enthusiasts who wrote their bikes. Next, we look at the most popular ones and deal with the main approaches to styling React components.


Evolution of approaches for styling React-components without Inline Styles



 /* Button.js */ import React, { Component } from 'react'; export default class Button extends Component { render() { return ( <div className = {'button ' + (this.props.isRed ? 'button--red' : '')}> <div className = 'button__caption'> {this.props.caption} </div> </div> ); } } 

 /* Button.css */ .button { line-height: 32px; border: 1px solid #000; } .button__caption { text-decoration: underline; text-align: center; } .button--red { background-color: red; } 


 /* ScopedSelectors.js */ import styles from './ScopedSelectors.css'; import React, { Component } from 'react'; export default class ScopedSelectors extends Component { render() { return ( <div className = {styles.root}> <p className = {styles.text}> Scoped Selectors </p> </div> ); } }; 

 /* ScopedSelectors.css */ .root { border-width: 2px; border-style: solid; border-color: #777; padding: 0 20px; margin: 0 6px; max-width: 400px; } .text { color: #777; font-size: 24px; font-family: helvetica, arial, sans-serif; font-weight: 600; } 

Using CSS Modules implies that style names will only be available locally, i.e. Each React component can have its own root style, and there will be no collisions - the names of the styles are transformed during assembly. It is also possible to define global styles that will be available everywhere - their names will not be transformed. To support CSS-Modules from the side of Node.js there is a project css-modules-require-hook , or you can use Webpack to compile the server application code (article about compiling the server code in two parts - 1 , 2 ).


About all these approaches, you can add that autoprefixer and all sorts of less , sass , postcss , stylus with constants, imports, mixins and other buns are successfully and easily screwed to them. Also, there are no problems with syntax highlighting and IDE hints. Within this list it will be easy to switch from one approach to another.


Styling React-components based on the ideas of Inline Styles


There are many solutions to this issue, they are very different and impose their only possible way of using them, with all the ensuing consequences: the complexity of migration to something else, their particular syntax, decorators, magic classes, from which you need to inherit - you will have to learn a new framework to use it. A number of solutions do not work with server rendering or do not support autoprefixer, which should be worked out at the compilation stage - do not drag it to the browser.


Consider some of the most famous representatives of this approach:


Radium


A good project that supports media queries and pseudo-classes, for example: hover. It offers the following syntax:


 const styles = { button: { padding: '1em', ':hover': { border: '1px solid black' }, '@media (max-width: 200px)': { width: '100%', ':hover': { background: 'white', } } }, primary: { background: 'green' }, warning: { background: 'yellow' }, }; ... <button style={[styles.button, styles.primary]}> Confirm </button> 

To make it all work, when declaring components you need to use the Radium decorator.


React Style


The same syntax is used as in standard Inline Styles for React, but with slightly advanced features .


 import StyleSheet from 'react-style'; const styles = StyleSheet.create({ primary: { background: 'green' }, warning: { background: 'yellow' }, button: { padding: '1em' }, // media queries '@media (max-width: 200px)': { button: { width: '100%' } } }); ... <button styles={[styles.button, styles.primary]}> Confirm </button> 

As in Radium, media queries work, but, unlike it, pseudo-classes and animation are not supported by CSS, there is a loader for Webpack.


Jss


Supports autoprefixer, pseudo-classes and media queries. Can be used with React via react-jss . There is also an experimental jss-loader for the webpack. Usage example:


 import classNames from 'classnames'; import useSheet from 'react-jss'; const styles = { button: { padding: '1em' }, 'media (max-width: 200px)': { button: { width: '100%' } }, primary: { background: 'green' }, warning: { background: 'yellow' } }; @useSheet(styles) export default class ConfirmButton extends React.Component { render() { const {classes} = this.props.sheet; return <button className={classNames(classes.button, classes.primary)}> Confirm </button>; } } 

jsxstyle


The project introduces its magic syntax, does not support media queries, but there is a loader for Webpack.


 // PrimaryButton component <button padding='1em' background='green' >Confirm</button> 

There is a good English-speaking review of all these technologies .


Conclusion


It is impossible to say unequivocally which of the solutions is better than the others - it all depends on specific tasks and restrictions. For some project, CSS-Modules are more suitable, another for BEM-naming for classes, the third for something based on the idea of ​​Inline Styles.


Choosing an approach for styling React components is a serious architectural decision that will leave its mark in the code of the entire project, will largely determine the tools for its development and will affect many other factors related to the support of the code and the speed of the application as a whole. I hope this review will be useful for Web developers as a brief background information on different approaches to styling React components and will help to assess the risks when choosing your own path.


')

Source: https://habr.com/ru/post/283314/


All Articles