Saturday, October 2, 2021

Apply CSS style to react material ui component

There are few ways to customize css style for native html elements (like button, div, etc) and React Material UI components (like Button, TextField, etc). Note when styles are specified as javascript or typescript object in Material UI syntac, the style attribute name is different from html css style attribute name, please refer to below link for more details.

https://mui.com/system/properties/

 

1. For Material UI components, if the css style applies to global scope, the best way to set it is in custom theme file as shown below:

const myTheme = createTheme({
    components: {
      MuiButton: {
        defaultProps:{
          disableElevation: true,
        },
        styleOverrides: {
          root: {
            borderRadius: '2em',
            width: '9em',
            textTransform: 'none',
            border: '1px solid #0076bf',
            color: '#fff',
            backgroundColor: '#0076bf',
            "&:hover" :{
              color: '#0076bf',
              backgroundColor: '#fff',
              borderr: '1px solid #0076bf',
            }
          }
        }
      }
    }
  });

  export default myTheme;

This method requires using Material UI style attribute name instead of html css style attribute name. For example, to change the background color, 'background-color' does not work, only backgroundColor will work. (The test shows bgcolor also does not work when specified in theme file, only backgroundColor works here).

If you need to customize native html element style in global css scope, then you can just use the old way to set it in a regular html css file.

2. When applying css style as named css class to certain elements including both Material UI component and native html elements.

This is a simple way to reuse the css style defined for regular html and css web projects. The style must be defined with specific css class name in a regular css file. Note in this way, you define css styles using regular html css attribute name and syntax, not Material UI's attribute names. Then in js (or jsx) file, importing the css file and apply the class styles to the corresponding elements.

The element must specify the class attribute name as 'className' instead of the regular 'class'. The reason of changing the name of 'class' to "className" is, js or jsx file is not regular html file, those jsx elements are not real html elements, and react needs to translate these jsx attributes to the regular html element attributes when running the function component method, where className will be translated to html 'class' attribute.  The below code applies row and mb-2 class style to div element

<div className="row mb-2">

As a react expression, className can also take react expression as value. React expression is wrapped by {}, so react expresion of {"row mb-2"} will just return the string of value of "row mb-2". So it has the same effect as 
<div className={"row mb-2"}

More important, when using react expression as class value, back tick can be used to dynamically set a sub react expression as class name, the sub react expression must be wrapped with ${}. For example:
<div className={`row mb-2 ${!isValid? 'invalidClassName' : 'validClassName'}`}

The css style defined in css file applies to global scope, so any elements having those style classe names will have those styles classes applied to them.
 
3. If you only want to apply a particular css style to a certain elements (native html elements or Material UI components), then you can apply the them as inline css style. This method specifies the style as React object, so the style attribute name must use the name defined by Material UI, not the html css style attribute name. 

The style attribute's value is a react expression (wrapped by {}) of a javascript object (wrapped by another {}), so the value is wrapped in {{}}.

<label style={{backgroundColor:'red', width:'100px'}}>hello</label>

The limitation of this method is it is hard to set complex styles, for example, no easy way to setup hover state styles for the elements.

4. For material ui components (not native html element), it can also set sx (system) attribute to define custom style based on theme. Note the style name used for sx needs to use material ui's style attribute name. The style will only apply to the current Material ui component.
<Stepper activeStep={activeStep} sx={{ pb: 3 , bgcolor: 'text.secondary'}}>
<Button sx={{
                                      color:'#0076bf',
                                      backgroundColor: '#fff',
                                      width: '9em',
                                      border: '0px',
                                      cursor: 'pointer',
                                      '&:hover':{
                                        textDecoration: 'underline',
                                      }
                                }} onClick={props.onPrev}>{t("button.previous")}</Button>
Please refer to https://mui.com/pt/system/the-sx-prop/ for available style names to be used by sx.


No comments:

Post a Comment