Стилизация компонентов пользовательского интерфейса материала

Не совсем проблема, но что-то меня не устраивает. Я использую react + typescript + css modules + https://material-ui-next.com/ . Проблема в том, что когда мне нужно стилизовать материальные компоненты пользовательского интерфейса, мне приходится часто использовать !important. Вопрос в том, есть ли способ создавать стили без important. Я создаю пример проекта для воспроизведения проблемы https://github.com/halkar/test-css-modules


person Artur Shamsutdinov    schedule 28.04.2018    source источник
comment
Вы используете Ангуляр? Попробуйте ::ng-deep{}   -  person John    schedule 28.04.2018
comment
@Джон, проверь теги ;)   -  person Artur Shamsutdinov    schedule 28.04.2018
comment
Да. Я пробовал несколько разных подходов из material-ui-next. .com/customization/overrides/, но все они заставляют меня использовать !important   -  person Artur Shamsutdinov    schedule 28.04.2018
comment
Удачи с этим? Я тоже категорически против css в js — это ужасно.   -  person Caspar Harmer    schedule 19.03.2020
comment
@CasparHarmer, посмотрите мой ответ ниже. JssProvider исправил проблему.   -  person Artur Shamsutdinov    schedule 20.03.2020


Ответы (3)


material-ui предоставляет возможность стилизации многих своих компонентов. Есть два способа сделать это.

Применение стилей глобально

Вы можете стилизовать компоненты глобально и применить их к теме. Примером этого может быть что-то вроде этого (скопировано из документов http://www.material-ui.com/#/customization/themes):

import React from 'react';
import {cyan500} from 'material-ui/styles/colors';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
import AppBar from 'material-ui/AppBar';

// This replaces the textColor value on the palette
// and then update the keys for each component that depends on it.
// More on Colors: http://www.material-ui.com/#/customization/colors
const muiTheme = getMuiTheme({
  palette: {
    textColor: cyan500,
  },
  appBar: {
    height: 50,
  },
});

class Main extends React.Component {
  render() {
    // MuiThemeProvider takes the theme as a property and passed it down the hierarchy
    // using React's context feature.
    return (
      <MuiThemeProvider muiTheme={muiTheme}>
        <AppBar title="My AppBar" />
      </MuiThemeProvider>
    );
  }
}

export default Main;

Как вы можете видеть здесь, компонент appBar имеет высоту 50 пикселей, что означает, что каждый раз, когда вы добавляете компонент панели приложений в свое приложение вниз по дереву, где вы применили muiTheme, он будет иметь высоту 50 пикселей. Это список всех стилей, которые вы можете применить для каждого компонента https://github.com/callemall/material-ui/blob/master/src/styles/getMuiTheme.js.

Применение стилей с помощью атрибута стиля

Чтобы применить стили к отдельным компонентам, обычно можно использовать свойство стиля и передавать ему нужные стили.

Это еще один пример из документации, где к RaisedButton применяется поле в 12 пикселей.

import React from 'react';
import RaisedButton from 'material-ui/RaisedButton';

const style = {
  margin: 12,
};

const RaisedButtonExampleSimple = () => (
  <div>
    <RaisedButton label="Default" style={style} />
    <RaisedButton label="Primary" primary={true} style={style} />
    <RaisedButton label="Secondary" secondary={true} style={style} />
    <RaisedButton label="Disabled" disabled={true} style={style} />
    <br />
    <br />
    <RaisedButton label="Full width" fullWidth={true} />
  </div>
);

export default RaisedButtonExampleSimple;

Теперь стили определены в том же файле, но вы можете определить их в отдельном файле и импортировать в файл, в котором вы используете компоненты.

Если вы хотите применить несколько стилей, вы можете использовать оператор распространения следующим образом: style={{...style1,...style2}}.

Обычно вы стилизуете определенную вещь в компоненте (корневом элементе) с помощью свойства стиля, но некоторые компоненты имеют более одного свойства для стилизации различных элементов компонента. Под свойствами на этой странице http://www.material-ui.com/#/components/raised-button, вы можете видеть, что есть свойство стиля, labelStyle и rippleStyle для стилизации различных частей RaisedButton.

Проверьте свойства компонента, который вы используете, и посмотрите, какое свойство стиля вы можете использовать, в противном случае проверьте доступные глобальные свойства стиля, которые вы можете переопределить. Надеюсь это поможет!

person Gautam Naik    schedule 28.04.2018
comment
Спасибо, но мой вопрос заключался в том, как я могу стилизовать компоненты материального пользовательского интерфейса с помощью css-модулей? Я категорически против CSS-in-JS. - person Artur Shamsutdinov; 28.04.2018

Я должен был использовать JssProvider и сказать ему помещать материальные стили пользовательского интерфейса перед моими в разделе страницы head.

import JssProvider from 'react-jss/lib/JssProvider';
import { create } from 'jss';
import { createGenerateClassName, jssPreset } from 'material-ui/styles';

const generateClassName = createGenerateClassName();
const jss = create(jssPreset());
// We define a custom insertion point that JSS will look for injecting the styles in the DOM.
jss.options.insertionPoint = document.getElementById('jss-insertion-point');

function App() {
  return (
    <JssProvider jss={jss} generateClassName={generateClassName}>
      ...
    </JssProvider>
  );
}

export default App;
person Artur Shamsutdinov    schedule 29.04.2018
comment
Документация по указанному выше решению — material-ui.com/customization /css-in-js/#css-injection-order - person cbaigorri; 25.10.2018

вы должны использовать API компонентов. Вы не можете установить стиль для компонентов, импортированных из библиотек, только с помощью css, если у компонента есть API для получения стиля.

*Обновлять

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

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

function Classes(props) {
  return (
    <Button
      classes={{
        root: props.classes.root, // class name, e.g. `classes-root-x`
        label: props.classes.label, // class name, e.g. `classes-label-x`
      }}
    >
      {props.children ? props.children : 'classes'}
    </Button>
  );
}

Classes.propTypes = {
  children: PropTypes.node,
  classes: PropTypes.object.isRequired,
};

export default withStyles(styles)(Classes);
person Mohammad Raha    schedule 28.04.2018
comment
Проблема в том, что я не понимаю, как я могу использовать их API с css-модулями без !important material-ui-next.com/customization/overrides/ - person Artur Shamsutdinov; 28.04.2018
comment
просмотрите документы и прочитайте образцы кода, чтобы узнать, как вы можете использовать их API. - person Mohammad Raha; 28.04.2018
comment
даже если вы хотите добавить класс к компоненту, в этом случае вы можете использовать classes API. - person Mohammad Raha; 28.04.2018
comment
ответ обновлен, он содержит пример переопределения стиля по классу - person Mohammad Raha; 28.04.2018
comment
Вы пробовали свой образец? Тем не менее, это потребует !important. Вы просто скопировали образец с их сайта. - person Artur Shamsutdinov; 28.04.2018
comment
что-то не так в вашем компоненте или конфигурации CSS, только из-за того, что этот API реализован так, чтобы делать то, что вы хотите, без important, пожалуйста, проверьте версию вашей библиотеки или что-то в этом роде. - person Mohammad Raha; 29.04.2018
comment
Я использую эти компоненты материала в своем проекте, и у меня нет проблем с пользовательским стилем CSS для его компонентов. вы можете проверить ссылку - person Mohammad Raha; 29.04.2018
comment
Прочитайте мой ответ выше. В моем приложении все правильно, но мне нужно заставить JssProvider ставить свои стили перед моими. - person Artur Shamsutdinov; 29.04.2018