Less — это популярное языковое расширение для CSS, которое позволяет делать много интересных вещей, о которых CSS может только мечтать. Сверхспособности Less проистекают из трех новых возможностей, которых нет в CSS, а именно вложенности селекторов, переменных и миксинов. Less вместе с Sass выбил из колеи веб-стили, когда они были изобретены 10 лет назад, потому что это позволило разработчикам писать стили ближе к тому, как они пишут javascript.
Итак, если Less так хорош, почему я пишу статью о том, как от него отказаться? В последнее время React набирает все большую популярность благодаря своей способности объединять отдельные компоненты для формирования пользовательского интерфейса.
Отличительной чертой React является то, что вы можете писать свой HTML вместе с вашим javascript, так что один компонент имеет весь соответствующий код вместе в одном месте. Styled-components — это альтернатива Less и Sass, использующая тот же способ организации. Теперь у вас могут быть составные части для вашего javascript, html и стилей, и вы можете написать все это, используя функции javascript. Это действительно лучший из миров!
Итак, если у меня есть старый код Less, как я могу преобразовать его в стилизованные компоненты?
Шаг 1. Установите глобальный стиль для всех глобальных таблиц стилей.
Мы берем любой глобальный стиль css и перемещаем его в глобальный стиль, обертывая его createGlobalStyle
.
import { createGlobalStyle } from 'styled-components'
export const GlobalStyle = createGlobalStyle`
@font-face {
font-family: "Roboto";
font-weight: normal;
src: local("Roboto"), url('https://fonts.google.com/...') format("truetype");
}
body {
font-family: "Roboto", sans-serif;
font-size: 12px;
color: black;
}
h1 {
font-size: 16px;
}
a {
text-decoration: none;
color: inherit;
}
`
Затем, когда мы определили этот компонент <GlobalStyle />
, мы добавляем его в корневой компонент нашего проекта:
const Layout = ({ children, title }) => (
<>
<GlobalStyle />
<Header />
<Page />
</Footer>
</>
)
Шаг 2. Переместите все переменные в стиль темы.
Styled-components предоставляет глобальный компонент темы, который вы можете определить в корне проекта, и он будет доступен везде. Допустим, это меньшее количество переменных, к которым мы хотим получить доступ для всего сайта:
@theme-text: #cccccc;
@label-theme: #2d5a6b;
@label-text: @theme-text;
@label-border: 1px solid @theme-text;
Мы создаем объект javascript с именем theme
, в котором мы можем хранить все наши константы. Каждый ключ в объекте будет представлять имя переменной, а значением будет значение, в котором он находится меньше.
Однако проблема с объектами javascript заключается в том, что одно значение не может ссылаться на другое значение в одном и том же объекте. Поэтому, если у меня есть значение color
и я хочу создать вторую переменную с именем backgroundColor
, обратную color
, мне не разрешено ссылаться на значение color
, когда оно находится в том же объекте, что и переменная. место, где я его устанавливаю.
Чтобы обойти это ограничение, мы начинаем с определения всего как отдельных строк. Поскольку одна строка может использовать информацию из другой строки, у нас нет проблем. Затем, когда у нас есть все наши строки, мы создаем один гигантский объект с именем theme
, и мы готовы к работе.
Итак, сначала мы преобразуем все наши переменные less в строки — будьте осторожны при переключении любых тире (-) на подчеркивание (_), потому что вы не можете использовать тире в имени переменной javascript. Когда мы создаем объект темы, мы можем иметь тире в имени ключа объекта, поэтому, если у нас есть переменная с именем less с именем @theme-text
и мы хотим придерживаться нотации змеиного регистра во всех наших стилизованных компонентах, мы можем создав ключ theme-text
в объекте theme
: theme['theme-text']
. Несколько строк кода стоят 1000 слов, поэтому я использовал следующий шаблон:
const color: '#442d6b';
const theme_text = '#cccccc';
const label_theme = '#2d5a6b';
const label_text = theme_text;
const label_border = `1px solid ${theme_text}`;
const theme = {
color, //I don't need color: color here because the names are the same
"theme-text": theme_text,
"label-theme": label_theme,
"label-text": label_text,
"label-border": label_border
}
export default theme;
Теперь нам нужно импортировать объект темы в объект <ThemeProvider>
в корне нашего проекта. Просто убедитесь, что мы экспортируем объект theme
, а затем импортируем его в корень проекта и используем с компонентом <ThemeProvider>
из библиотеки styled-components:
import { ThemeProvider } from 'styled-components'
import theme from './theme' //This is the theme object that we defined above
const Layout = ({ children, title }) => (
<>
<ThemeProvider theme={myTheme}>
<GlobalStyle />
<Header />
<Page />
</Footer>
</ThemeProvider>
</>
)
Теперь у нас будет доступ ко всему в объекте темы в качестве параметра во всех наших стилизованных компонентах, которые являются дочерними элементами <ThemeProvider>
. Мы покажем вам, как это сделать в шаге 4, а затем мы должны показать вам, как скопировать остальные стили.
Шаг 3. Разбейте меньшее количество компонентов на фрагменты стилей, которые можно прикрепить к реагирующим компонентам.
Поскольку основным преимуществом использования React является его компоновка, теперь нам нужно разбить единственную таблицу стилей less на отдельные фрагменты. Это не так плохо, как кажется, например, если бы у нас был класс с именем blogItem, у которого была куча меньшего, что стилизовало карточку товара, мы создаем стилизованный компонент с именем BlogItem и копируем в него все стили. Вы можете сохранить все вложенные стили и медиа-запросы на месте.
.blogItem {
font-size: 12px;
margin-top: 24px;
//..many more stylings excluded
}
идет к:
export const StyledBlogItem = styled.div`
font-size: 12px;
margin-top: 24px;
//...many more stylings excluded
`
export const BlogItem = props => <StyledBlogItem props={props} />
Шаг 4. Преобразуйте все переменные, на которые есть ссылки в таблицах стилей less
Теперь, когда у нас скопирована большая часть кода таблицы стилей, нам нужно разобраться с переменными. Поскольку эти переменные теперь определены в нашей теме, мы можем получить к ним доступ в любом стилизованном компоненте, используя параметр темы следующим образом:
import styled from 'styled-components'
export const BlogItem = styled.div`
${({ theme }) => `
color: theme['color'];
`}
`
Единственная проблема здесь в том, что вам нужно следить за любым местом, где переменная с меньшим значением умножается или делится на число. Примеры этого включают умножение размера шрифта, радиуса границы или толщины границы на константу. В этом примере ниже у нас есть переменная less с именем global-border-radius
, которую мы определяем как 12px. Можно получить меньший радиус границы, разделив его на число в другом месте таблицы стилей. Здесь класс blogItem будет иметь радиус границы 6 пикселей, хотя глобальное значение равно 12 пикселей.
@global-border-radius: 12px;
.blogItem {
border-radius: @global-border-radius / 2;
}
Стилизованные компоненты не могут с этим справиться, потому что вы, по сути, пытаетесь разделить строку 12px
на число 2
. Вот функция, которую вы можете скопировать и использовать, которая сделает это за вас автоматически:
export const modifySize = (fontString, modifyFrac) => {
const fontNumber = parseFloat(fontString)
const fontUnit = fontString.replace(/[0-9]/g, '')
return `${fontNumber * modifyFrac}${fontUnit}`
}
const BlogItem = styled.div`
${({theme})=> `
border-radius: `${modifySize(theme['global-border-radius'], 2)}`
`}
`
Наша функция modifySize
разбивает строку 12px
на число 12
и строку px
. Он изменит число по коэффициенту, который вы передадите, и вернет строку с правильным размером.
Шаг 5. Преобразуйте примеси в функции
Миксины — это способ сделать небольшой фрагмент стилей, который вы можете применить к ряду элементов. Вот миксин, который устанавливает различные параметры для заголовка:
heading (@selector, @size, @color: @theme-title) {
text-align: center;
font-size: @size;
font-weight: bold;
color: @color;
}
Мы можем уловить ту же суть, создав функцию, которая будет возвращать строку со всей этой информацией о стилях, а styled-components с радостью добавит ее туда, куда вы пожелаете:
export const heading = (theme, size, color) => {
const setColor = color ? color : theme['theme-title']
//I can set a default color if color isn't passed in
return `
text-align: center;
font-size: ${size};
font-weight: bold;
color: ${setColor};
`
}
Самое классное в этом то, что если мы захотим, мы можем даже передавать переменные для управления выводом функции. Единственная загвоздка в том, что если вам нужен доступ к глобальным переменным, вам нужно передать параметр темы в функцию — он не будет автоматически параметром, как при создании стилизованных компонентов. Мы можем вызвать функцию heading
следующим образом:
const BlogHeading = styled.div`
${({ theme }) => `
${heading(theme, '16px', 'black')}
`}
`
Шаг 6. Используйте && для стилей и стилей с разбросом
Для большинства конверсий первых 4 шагов должно быть достаточно, но время от времени у вас будут некоторые стили, которые не будут реализованы. Я столкнулся с этим в одном случае, когда у меня была таблица стилей css, которая формировала мой базовый стиль, а затем, когда я пытался переопределить ее с помощью своего стилизованного компонента, базовый стиль постоянно оставался.
базовый css:
:not(pre) > code[class*='language-'],
pre[class*='language-'] {
background-color: #fdf6e3;
}
меньше стайлинга:
:not(pre) > code[class*='language-'] {
font-family: 'Roboto-Mono';
padding: 0.1em;
border-radius: @border-radius-small;
background-color: @post-highlight;
color: @post-highlight-text;
}
Решение состоит в том, чтобы добавить &&
перед стилем, который остался. Каждый &
будет увеличивать сгенерированное className для каждого &
, который вы добавляете.
const StyledContent = styled.div`
${({ theme }) => `
&& :not(pre) > code[class*='language-'] {
font-family: 'Roboto-Mono';
padding: 0.1em;
border-radius: ${theme['border-radius-small']};
background-color: ${theme['post-highlight']};
color: ${theme['post-highlight-text']};
background-color: purple;
}
`}
`
Есть еще кое-что!
Нажмите здесь, чтобы дать нам свой адрес электронной почты, и мы сообщим вам, когда опубликуем новые материалы. Мы уважаем конфиденциальность вашей электронной почты, мы никогда не будем спамить вас, и вы можете отказаться от подписки в любое время.
Первоначально опубликовано наhttps://www.codemochi.com/.