Каждый сталкивался со случаем, когда нужно подстроить компоненты React под особый дизайн, верно? Может быть, у вас даже есть UI-кит, но дизайнер считает, что это особый случай и нужно сделать эту кнопку больше и ярче? Так вот, у меня есть простой способ решить эту проблему. Скажите «Нет» своему дизайнеру. И все. Пока.
Это шутка. Я думаю, что работа инженера-программиста связана с поиском компромиссов, и иногда мы должны делать то, что хочет дизайнер. Итак, я хочу рассказать о простом способе кастомизации компонентов в React.
Наивный способ
Предположим, у вас есть кнопка.
export const Button = ({ text, onClick }) => {
return (
<button className="button" onClick={onClick}>
{text}
</button>
);
};
С помощью этого css:
.button {
padding: 12px 26px;
background-color: skyblue;
color: #ffffff;
font-size: 1rem;
}
А теперь вам нужно увеличить padding и изменить цвет:
Какой самый простой способ сделать это? Бросить имя дополнительного класса в props и использовать его:
export const Button = ({ text, onClick, className }) => {
return (
<button className={cn('button', className)} onClick={onClick}>
{text}
</button>
);
};
Я использовал эту библиотеку для конкатенации className с классом .button
Итак, у нас есть новый класс:
.secondary-button {
padding: 20px 32px;
color: #000000;
}
Использование:
<Button text="Press me" className="secondary-button" />
Все хорошо, но недавно ваш коллега поменял главную кнопку:
export const Button = ({ text, additionalText, onClick, className }) => {
return (
<button className={cn("button", className)} onClick={onClick}>
<span className="button__text">{text}</span>
<span>{additionalText}</span>
</button>
);
};
И css:
.button {
background-color: skyblue;
font-size: 1rem;
}
.button__text {
display: inline-block;
color: #ffffff;
padding: 12px 26px;
}
А что случилось с вашей кнопкой? Ваши стили сломались, потому что ваш селектор не такой сильный, как новый для текста. Значит, у вас ошибка.
Да, вы можете просто передать новый класс только для текста, и все будет работать хорошо, но как долго?
У меня есть более безопасный и более мощный способ настройки ваших компонентов.
CSS-переменные
Все знают, как инициализировать переменные css в :root (это просто псевдоним для <html>
, но более конкретный):
:root {
--main-color: #ffffff;
}
Мы также можем использовать css-вары в других селекторах, например, в классе:
.some-class {
--main-color: gray;
}
И эти переменные также используют наследование, как свойства CSS.
Итак, вы думаете так же, как и я? Мы можем использовать их для настройки вашего компонента!
.button {
--button-padding: 12px 26px;
--button-color: #ffffff;
padding: var(--button-padding);
color: var(--button-color);
background-color: skyblue;
font-size: 1rem;
}
Посмотрите на код выше. Мы объявляем переменные и используем их в нашей первой версии кнопки. Теперь, если вы захотите изменить padding или цвет, вам придется написать что-то подобное:
.secondary-button {
--button-padding: 20px 32px;
--button-color: #000000;
}
Когда кто-то захочет изменить внутренний css-код этой кнопки, вы можете быть спокойны — все будет работать хорошо:
.button {
--button-padding: 12px 26px;
--button-color: #ffffff;
background-color: skyblue;
}
.button__text {
display: inline-block;
padding: var(--button-padding);
color: var(--button-color);
}
Итак, мы пишем CSS-код с низкой связностью, с меньшим количеством ошибок и большей возможностью повторного использования!
Мы можем использовать css-вары с контейнерами, например, так:
export const Button = ({ text }) => {
return (
<button className="button">{text}</button>
);
};
.button {
display: inline-block;
/* Using default values var(--name, <default value>) */
background-color: var(--button-bg-color, skyblue);
color: var(--button-color, #ffffff);
}
Теперь мы можем инициализировать переменные --button-bg-color
и --button-color
в родительском компоненте Button и все!
Давайте создадим класс карточки и обернем в него кнопку:
.card {
--button-color: #000;
--button-bg-color: peachpuff;
}
<div>
<Button text="Default button"/>
<div className="card">
<Button text="Button into card"/>
</div>
</div>
Заключение
CSS переменные могут помочь вам создать многократно используемые компоненты и уменьшить количество ошибок не только с React, но и с другими фреймворками или без них! В любом случае, я надеюсь, что эта статья была интересной, и вы начнете использовать CSS-переменные в своей работе!