Стилизация
1. Инлайн CSS
const buttonStyles = {
display: 'inline-flex',
margin: '0 4px',
padding: '8px 24px',
border: 0,
borderRadius: 2,
fontSize: 14,
fontFamily: 'inherit',
};
const Button = ({ type = 'button', label, disabled }) => (
<button
type={type}
disabled={disabled}
style={{
...buttonStyles,
backgroundColor: disabled ? '#0000001f' : '#2196f3',
color: disabled ? '#00000042' : '#ffffff',
}}
>
{label}
</button>
);
Плохая производительность
Не масштабируется
Ограниченные возможности (псевдоэлементы, медиа и т. п.)
Нет инструментов и сложно дебажить.
2. Ванильный CSS или SASS
/* Button.css */
.Button {
display: inline-flex;
margin: 0 4px;
padding: 8px 24px;
border: 0;
border-radius: 2px;
color: #ffffff;
font-size: 14px;
font-family: inherit;
background-color: #2196f3;
transition: background-color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;
}
.Button:hover,
.Button:focus {
background-color: #1976d2;
}
.Button-disabled {
background-color: #0000001f;
color: #00000042;
}
// Button.js
import './Button.css';
const Button = ({ type = 'button', label, disabled }) => {
const btnClasses = ['Button'];
if (disabled) {
btnClasses.push('Button-disabled');
}
return (
<button type={type} disabled={disabled} className={btnClasses.join(' ')}>
{label}
</button>
);
};
Ванильный CSS не масштабируется
Глобальное пространство имен
Приходится использовать BEM-нотацию
Вложенность селекторов без BEM
Проблематичное удаление мертвого кода
3. CSS-модули
Согласно определению из репозитория, CSS-модули — это CSS-файлы, в которых все классы по умолчанию находятся в локальной области видимости. Этот подход был разработан, что бы решить проблему глобальной области видимости в CSS.
CSS-модули — это не официальная спецификация, они не имплементированы в браузеры. Это процесс, запускаемый на стадии сборки проекта (например, с помощью Webpack), в результате выполнения которого имена классов и селекторы изменяются так, чтобы образовалась своего рода локальная область видимости (что-то вроде пространства имен).
CSS-модули гарантируют, что все стили одного компонента:
Находятся в одном месте
Применяются только к этому компоненту и никакому другому
Create React App поддерживает CSS-модули из коробки, все что необходимо сделать это называть файлы стилей согласно конвенции [name].module.css
.
Использование напоминает обычный CSS, за тем исключением, что все имена классов обфусцируются. В результирующем CSS получаем уникальное имя класса в формате [filename]\_[classname]\_\_[hash]
. CSS-модули решают проблему глобального пространства имен с помощью маппинга классов из CSS-файла в объект с ключами по имени класса.
/* Button.module.css */
.button {
display: inline-flex;
margin: 0 4px;
padding: 8px 24px;
border: 0;
border-radius: 2px;
color: #ffffff;
font-size: 14px;
font-family: inherit;
background-color: #2196f3;
transition: background-color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;
}
.button:hover,
.button:focus {
background-color: #1976d2;
}
.disabled {
background-color: #0000001f;
color: #00000042;
}
// Button.js
import styles from './Button.module.css';
const Button = ({ type = 'button', label, disabled }) => {
const btnClasses = [styles.button];
if (disabled) {
btnClasses.push(styles.disabled);
}
return (
<button className={btnClasses.join(' ')} type={type} disabled={disabled}>
{label}
</button>
);
};
3.1. Композиция
В CSS-модулях можно делать композицию стилей прямо в CSS-файле с помощью свойства composes
, как @extends
в SASS
.
/* Button.module.css */
.button {
display: inline-flex;
margin: 0 4px;
padding: 8px 24px;
border: 0;
border-radius: 2px;
font-size: 14px;
font-family: inherit;
transition: background-color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;
}
.button:hover,
.button:focus {
background-color: #1976d2;
}
.active {
composes: button;
color: #ffffff;
background-color: #2196f3;
}
.disabled {
composes: button;
color: #00000042;
background-color: #0000001f;
}
// Button.js
import styles from './Button.module.css';
const Button = ({ type = 'button', label, disabled }) => {
const btnClass = disabled ? styles.disabled : styles.active;
return (
<button className={btnClass} type={type} disabled={disabled}>
{label}
</button>
);
};
3.2. Переменные
В CSS-модулях также есть возможность использовать переменные.
/* variables.module.css */
@value font-stack: Roboto, Arial, sans-serif;
/* Button.module.css */
@value font-stack from 'path/to/variables.module.css';
.button {
font-family: font-stack;
}
3.3. Глобальные стили
Для того чтобы сделать стиль глобальным, необходимо обернуть селектор в конструкцию :global(selector)
. Селекторы тегов по умолчанию будут в глобальной области видимости, CSS-модули обфусцируют только классы.
/* Глобален по умолчанию */
body {
color: #fff;
font-size: 16px;
}
/* Так класс можно сделать глобальным */
:global(.my-class) {
color: #2196f3;
}
4. Styled Components
styled-components дает возможность написания CSS в JavaScript используя т.н. тегированные шаблонные строки. Библиотека удаляет сопоставление между компонентами и стилями — компонент превращается в конструкцию с низкоуровневой стилизацией.
import React, { Component } from 'react';
import styled from 'styled-components';
const Title = styled.h1`
color: white;
`;
const Wrapper = styled.div`
background: black
`;
class App extends Component {
render() {
return (
<Wrapper>
<Title>Hello World!</Title>
</Wrapper>
);
}
}
export default App;
5. Дополнительные материалы
Last updated
Was this helpful?