5 вещей, которые вы можете сделать в CSS-in-JS, но о которых вы не знали

5 вещей, которые вы можете сделать в CSS-in-JS, но о которых вы не знали

От автора: в дополнение к традиционному CSS вы также имеете встроенные стили и CSS in JS в качестве вариантов стилизации приложения React.

С помощью встроенных стилей вы передаете объект JavaScript в атрибут style:

const myStyle = { fontSize: 24, lineHeight: '1.3em', fontWeight: 'bold',
}; <span style={myStyle}>Hello World!</p>

Однако не все функции CSS поддерживаются. С другой стороны, CSS-in-JS — это метод, в котором JavaScript используется для стилизации компонентов. Когда анализируется этот JavaScript, генерируется CSS (обычно как элемент style) и присоединяется к DOM.

Этот функционал реализуется сторонними библиотеками. Например, вот предыдущий пример, реализованный с помощью Aphrodite:

import { StyleSheet, css } from 'aphrodite';
const styles = StyleSheet.create({ myStyle: { fontSize: 24, lineHeight: '1.3em', fontWeight: 'bold', }
}); <span className={css(styles.myStyle)}>Hello World!</p>

Другие библиотеки, которые я могу порекомендовать:

Я не однозначный приверженец CSS-in-JS, но я должен сказать, что некоторые из этих библиотек добавляют поддержку функций, которые могут оказаться полезными в определенных ситуациях.

В этом посте я расскажу о пяти вещах, которые вы можете сделать в CSS-in-JS с помощью вышеупомянутых библиотек, и, я уверен, вы не знали о них.

1. Вы можете обратиться к другим стилизованным компонентам

Библиотеки, такие как styled-components и emotion, позволяют использовать для создания компонентов React из стилей тегированные литералы шаблонов:

import styled from 'styled-components';
// Создаем компонент, который отображает элемент <p> с синим текстом
const BlueText = styled.p` color: blue;
`; <BlueText>My blue text</BlueText>

Но они также позволяют настраивать таргетинг на другие стилизованные компоненты (например, если вы использовали селектор CSS):

const ImportantText = styled.div` font-weight: bold;
`; const Text = styled.div` color: gray; ${ImportantText} { font-style: italic; }
`; render( <div> <Text> Text in gray <ImportantText>Important text in gray, bold and italic</ImportantText> </Text> <ImportantText>Important text bold</ImportantText> </div>
);

Это полезно, когда вы комбинирует псевдо-классы, например, чтобы изменить цвет компонента при наведении курсора:

const Text = styled.div` color: gray; &:hover ${ImportantText} { color: red; }
`;

2. Вы можете расширить функции некоторых библиотек с помощью JSS (или других библиотек)

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

Однако есть два проекта, которые объединяют ядро JSS с Aphrodite и styled-components: aphrodite-jss и styled-jss. Таким образом, вы можете сохранить лучшие функции Aphrodite (или styled-components) и использовать все функции и плагины JSS, от кэширования правил до изоляции правил и тем, пакета темизации, который предоставляет следующие компоненты более высокого порядка:

ThemeProvider, который передает объект темы вниз по дереву React по контексту.

withTheme, который позволяет получать объект темы и его обновления в качестве свойства.

Например:

const blackTheme = { color: 'black',
}; const App = () => ( <ThemeProvider theme={blackTheme}> <MyComponent /> </ThemeProvider>
);

При применении Aphrodite и тем, в качестве другого примера, вы также можете использовать react-with-styles, который, в частности, взаимодействует с Aphrodite и JSS, чтобы получить доступ к информации о теме при определении стилей.

3. Цепочка нескольких анимаций с помощью ключевых кадров

В отличие от встроенных стилей, CSS-in-JS позволяет вам определять анимацию с использованием ключевых кадров. Например, вот как это делается с помощью styled-components:

const heightAnimation = keyframes` 0% { height: 0; } 100% { height: 200; }
`; const myComponent = styled.div` display: inline-block; width: 200; position: relative; animation-name: ${heightAnimation}; animation-duration: 1.5s; animation-timing-function: ease;
`;

Но мало кто знает, что вы можете связать несколько анимаций, используя более одного объекта ключевых кадров в свойстве animation. Вот приведенный выше пример, измененный с объединением двух анимаций:

const heightAnimation = keyframes` 0% { height: 0; } 100% { height: 200; }
`; const rotateAnimation = keyframes` 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); }
`; const myComponent = styled.div` display: inline-block; width: 200; position: relative; animation: ${props => css` ${heightAnimation} 1.5s ease infinite, ${rotateAnimation} 1.5s linear infinite `}
`;

Radium — это еще одна библиотека, которая поддерживает несколько анимаций, с помощью передачи массива объектов ключевых кадров в качестве значения свойства animationName:

const heightAnimation = Radium.keyframes( { 0% { height: 0; } 100% { height: 200; } }, 'myHeightAnimation',
); const rotateAnimation = Radium.keyframes( { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }, 'myRotateAnimation',
); const styles = { myStyle: { animationName: [heightAnimation, rotateAnimation], animationDuration: '1.5s, 1s', animationIterationCount: 'infinite, infinite', animationTimingFunction: 'ease, linear', display: inline-block; width: 200; position: relative; },
};

4. Объявление глобальных стилей

Все в CSS является глобальным, и одной из целей использования CSS-in-JS является устранение глобальных определений стиля.

Однако применения глобальных стилей могут быть допустимые, например, когда вы хотите применять одни и те же стили шрифтов к каждому элементу страницы.

Конечно, вы всегда можете использовать традиционный CSS, импортируя его через Webpack или объявляя в файле index.html. Но если вы серьезно относитесь к использованию JavaScript для всех своих стилей, некоторые библиотеки фактически позволяют вам определять глобальные стили с помощью вспомогательных компонентов или расширений / плагинов.

В Radium вы можете использовать компонент Style для визуализации стилизованного элемента с глобальными стилями. Например:

<Style rules={{ body: { fontFamily: 'Arial, Helvetica, sans-serif' } }}
/>

Возвращает:

<style>
body { font-family: 'Arial, Helvetica, sans-serif';
}
</style>

JSS использует плагин для написания глобальных стилей:

const styles = { '@global': { body: { fontFamily: 'Arial, Helvetica, sans-serif' } }
}

А в Aphrodite вы можете использовать для этого стороннее расширение:

import {injectGlobalStyles} from "aphrodite-globals"; injectGlobalStyles({ "body": { fontFamily: 'Arial, Helvetica, sans-serif', }
});

Или aphrodite-jss, чтобы использовать глобальный плагин JSS.

5. Протестируйте компонент со стилями в модульных тестах

Некоторые библиотеки содержат утилиты для тестирования компонентов со стилями. Aphrodite предоставляет недокументированный (по крайней мере, на момент написания этой статьи) объект StyleSheetTestUtils, который доступен только для непроизводственных сред (process.env.NODE_ENV !== ‘production’) и содержит три метода:

suppressStyleInjection, которые предотвращают ввод стилей в DOM, и это полезно, если вы хотите протестировать вывод компонентов Aphrodite, когда у вас нет DOM.

clearBufferAndResumeStyleInjection, который делает противоположное suppressStyleInjection и должен использоваться в паре с ним.

getBufferedStyles — возвращает строку буферизованных стилей, которые не были очищены.

Вот пример того, как они используются:

import { StyleSheetTestUtils, css } from 'aphrodite';
//... beforeEach(() => { StyleSheetTestUtils.suppressStyleInjection();
}); afterEach(() => { StyleSheetTestUtils.clearBufferAndResumeStyleInjection();
}); test('my test', () => { const sheet = StyleSheet.create({ background: { backgroundColor: 'blue' }, }); css(sheet.background); // буфер содержит что-тонаподобие [ ".background_k554e1{background-color:blue !important;}" ] const buffer = StyleSheetTestUtils.getBufferedStyles(); // ...
});

Radium — это еще один пример. Он имеет объект TestMode для управления внутренним состоянием и поведением во время тестов с помощью методов clearState, enable и disable. Здесь вы можете найти пример того, как он используется.

Заключение

CSS-in-JS — это инструмент для стилизации приложений с использованием JavaScript, и вы можете делать очень интересные вещи с помощью библиотек, которые его реализуют.

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

На этой странице вы можете найти экспериментальную площадку, где вы можете протестировать и сравнить многие библиотеки CSS-in-JS.

С другой стороны, есть и другие библиотеки, которые немного по другому реализуют концепции CSS, JavaScript и типов.
Одна из таких библиотек — stylable, основанная на компонентах библиотека с препроцессором, которая преобразует CSS Stylable в минимизированный и кросс-браузерный vanilla CSS. Вот отличная презентация этой библиотеки и CSS-in-JS в целом. Очень рекомендую.

Автор: Esteban Herrera

Источник: https://blog.logrocket.com/

Редакция: Команда webformyself.