Saltar al contenido

🎉 Material UI v5 is out now! Check out the announcement blog post

@material-ui/styles

Puede utilizar la solución de estilo de Material-UI en su aplicación, tanto si está usando o no componentes de Material-UI.

Material UI busca proveer fundamentos sólidos para la construcción de UIs de manera dinámica. For the sake of simplicity, we expose the styling solution used in Material-UI components as the @material-ui/styles package. You can use it, but you don't have to, since Material-UI is also interoperable with all the other major styling solutions.

¿Por qué usar la solución de estilo de Material-UI?

En versiones anteriores, Material-UI usaba LESS. Luego utilizaba una solución a medida para escribir los estilos de los componentes componentes pero ambas soluciones resultaron ser limitadas. A CSS-in-JS solution overcomes many of those limitations, and unlocks many great features (theme nesting, dynamic styles, self-support, etc.).

Material-UI's styling solution is inspired by many other styling libraries such as styled-components and emotion.

  • Podes esperar las mismas ventajas que las que tenían los componentes con estilos.
  • 🚀 Es ultra rápida.
  • 🧩 Es extensible a través de una plugin API.
  • ⚡ Utiliza JSS en su núcleo – un compilador de JavaScript a CSS de alto rendimiento que funciona en tiempo de ejecución y por el lado del servidor.
  • 📦 Less than 15 KB comprimido; and no bundle size increase if used alongside Material-UI.

Instalación

@material-ui/styles es reexportado como @material-ui/core/styles - sólo necesitas instalarlo si deseas usarlo independientemente de Material-UI.

Para instalarlo y guardarlo en las dependencias de tu package.json, ejecuta:

// with npm
npm install @material-ui/styles

// with yarn
yarn add @material-ui/styles

Primeros pasos

There are 3 possible APIs you can use to generate and apply styles, however they all share the same underlying logic.

Hook API

import React from 'react';
import { makeStyles } from '@material-ui/core/styles';
import Button from '@material-ui/core/Button';

const useStyles = makeStyles({
  root: {
    background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
    border: 0,
    borderRadius: 3,
    boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)',
    color: 'white',
    height: 48,
    padding: '0 30px',
  },
});

export default function Hook() {
  const classes = useStyles();
  return <Button className={classes.root}>Hook</Button>;
}
<Button className={classes.root}>Styled with Hook API</Button>

API de Styled components

Note: this only applies to the calling syntax – style definitions still use a JSS object. You can also change this behavior, with some limitations.

import React from 'react';
import { styled } from '@material-ui/core/styles';
import Button from '@material-ui/core/Button';

const MyButton = styled(Button)({
  background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
  border: 0,
  borderRadius: 3,
  boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)',
  color: 'white',
  height: 48,
  padding: '0 30px',
});

export default function StyledComponents() {
  return <MyButton>Styled Components</MyButton>;
}
<MyButton>Styled with styled-components API</MyButton>

Higher-order component API

import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/core/styles';
import Button from '@material-ui/core/Button';

const styles = {
  root: {
    background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
    border: 0,
    borderRadius: 3,
    boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)',
    color: 'white',
    height: 48,
    padding: '0 30px',
  },
};

function HigherOrderComponent(props) {
  const { classes } = props;
  return <Button className={classes.root}>Higher-order component</Button>;
}

HigherOrderComponent.propTypes = {
  classes: PropTypes.object.isRequired,
};

export default withStyles(styles)(HigherOrderComponent);

Nesting selectors

You can nest selectors to target elements inside the current class or component. The following example uses the Hook API, but it works the same way with the other APIs.

const useStyles = makeStyles({
  root: {
    color: 'red',
    '& p': {
      color: 'green',
      '& span': {
        color: 'blue'
      }
    }
  },
});
This is red since it is inside the root.

This is green since it is inside the paragraph and this is blue since it is inside the span

Adapting based on props

You can pass a function to makeStyles ("interpolation") in order to adapt the generated value based on the component's props. The function can be provided at the style rule level, or at the CSS property level:

const useStyles = makeStyles({
  // style rule
  foo: props => ({
    backgroundColor: props.backgroundColor,
  }),
  bar: {
    // CSS property
    color: props => props.color,
  },
});

function MyComponent() {
  // Simulated props for the purpose of the example
  const props = { backgroundColor: 'black', color: 'white' };
  // Pass the props as the first argument of useStyles()
  const classes = useStyles(props);

  return <div className={`${classes.foo} ${classes.bar}`} />
}

This button component has a color property that changes its color:

Adapting the hook API

<React.Fragment>
  <MyButton color="red">Red</MyButton>
  <MyButton color="blue">Blue</MyButton>
</React.Fragment>

Adapting the styled components API

<React.Fragment>
  <MyButton color="red">Red</MyButton>
  <MyButton color="blue">Blue</MyButton>
</React.Fragment>

Adapting the higher-order component API

<React.Fragment>
  <MyButton color="red">Red</MyButton>
  <MyButton color="blue">Blue</MyButton>
</React.Fragment>

Stress test

In the following stress test, you can update the theme color and the background-color property live:

const useStyles = makeStyles(theme => ({
  root: props => ({
    backgroundColor: props.backgroundColor,
    color: theme.color,
  }),
}));
rendered 1 times
color: #ffffff
backgroundColor: #2196f3

@material-ui/core/styles vs @material-ui/styles

Material-UI's styles are powered by the @material-ui/styles package, (built with JSS). This solution is isolated. It doesn't have a default theme, and can be used to style React applications that are not using Material-UI components.

To reduce the number of packages to install when using Material-UI, and to simplify the imports, @material-ui/styles modules are re-exported from @material-ui/core/styles.

To remove the need to systematically supply a theme, the default Material-UI theme is applied to the re-exported makeStyles, styled, withTheme, useTheme, and withStyles modules.

Por ejemplo:

// Re-export with a default theme
import { makeStyles } from '@material-ui/core/styles';

// Original module with no default theme
import { makeStyles } from '@material-ui/styles';