最小CSS In-JS樣式的組件解決方案用於React。
也有一些非目標。
as屬性, .withComponent()方法).attrs()方法)defaultProps 。 import { styled } from '@minstack/styled' ;使用標籤名稱樣式任何HTML元素類型。樣式的組件支持HTML元素支持的所有相同的道具(包括轉發的參考)。
const StyledComponent = styled ( 'div' ) `
color: black;
` ;標籤名稱方法樣式也得到了支持。
const StyledComponent = styled . div `
color: black;
` ;樣式任何接受className屬性的React組件,或擴展已經樣式的組件的樣式。
const StyledComponent = styled ( Component ) `
color: black;
` ; 通過設置模板字符串的通用參數,可以將額外的屬性添加到樣式組件中。通常,樣式屬性應以$為前綴,以表明它們僅用於樣式。以$字符開頭的任何屬性名稱都不會作為屬性傳遞到基礎HTML元素。
interface ComponentStyleProps {
$font ?: string ;
}
const StyledComponent = styled ( 'div' ) < ComponentStyleProps > `
font-family: ${ ( props ) => props . $font } ;
` ; 使用styled.global global實用程序來創建全局樣式組件。
const GlobalStyle = styled . global `
body,
html {
margin: 0;
padding: 0;
}
` ;樣式屬性也可以添加到全球樣式中。
interface GlobalStyleProps {
$font ?: string ;
}
const GlobalStyle = styled . global < GlobalStyleProps > `
body,
html {
font-family: ${ ( props ) => props . $font } ;
}
` ;定義密鑰幀或字體尺寸與定義任何其他樣式相同。由於它們沒有範圍為任何特定組件,因此它們可能僅在全球樣式中使用。為防止名稱碰撞,請使用隨附的getId實用程序生成CSS安全的唯一名稱。
const openSansFont = getId ( 'font/open-sans' ) ;
const slideInAnimation = getId ( 'keyframes/slide-in' ) ;
const GlobalStyle = styled . global `
@font-face {
font-family: ${ openSansFont } ;
src: url('/fonts/OpenSans-Regular-webfont.woff') format('woff');
}
@keyframes ${ slideInAnimation } {
from {
transform: translateX(0%);
}
to {
transform: translateX(100%);
}
}
` ;
const StyledComponent = styled ( 'div' ) `
font-family: ${ openSansFont } ;
animation-name: ${ slideInAnimation } ;
` ; 傳遞主題掛鉤(或任何功能),該掛鉤將主題返回到createStyled實用程序中。然後,當第二個參數傳遞給任何樣式的模板字符串功能值時,主題值將可用。
// File: styled-with-theme.ts
import { createStyled } from '@minstack/styled' ;
export const styled = createStyled ( useTheme ) ;這會創建一個強烈鍵入styled實例。使用此實例而不是內置實例。
import { styled } from './styled-with-theme' ;
const ThemedComponent = styled ( 'div' ) `
color: ${ ( props , theme ) => theme . fgColor } ;
background-color: ${ ( props , theme ) => theme . bgColor } ;
` ; 支持所有CSS和嵌套。
要將樣式直接應用於已設計的HTML元素或組件,請在標記模板的頂部使用CSS屬性(無周圍塊)。
const StyledComponent = styled ( 'div' ) `
color: red;
` ;頂級CSS屬性將包裹在動態樣式的類選擇器中
. _rmsds7y13d_ {
color : red;
}使用CSS規則塊為樣式組件的兒童設計樣式。
const StyledComponent = styled ( 'div' ) `
.child {
color: blue;
}
` ;樣式的動態類將自動添加到所有選擇器上,以使其“範圍”。
. _rmsds7y13d_ . child {
color : blue;
}每個樣式的組件(除全局樣式除外)都可以用作選擇器。
const StyledComponentA = styled ( 'div' ) `
color: blue;
` ;
const StyledComponentB = styled ( 'div' ) `
${ StyledComponentA } {
background-color: yellow;
}
` ;每個樣式的組件都有一個獨特的靜態類,該類別是在創建中生成的。樣式"._rmsss7y13d_"組件的toString()方法返回該靜態類的選擇器字符串(例如。
. _rmsds7y13d_ . _rmsss7y13d_ {
color : red;
}靜態類是從組件的顯示名稱,樣式模板的靜態部分,繼承的靜態類(擴展另一個樣式組件)以及共享相同“ thumbprint”的先前創建的組件的數量。在大多數情況下,這應該使SSR和客戶端渲染的靜態類穩定。如果發生靜態類SSR問題,則可能是由於具有相同指紋的組件具有不穩定的創建順序。嘗試使用.withConfig()方法更改displayName ,以使有問題的組件的指紋獨特。
const StyledComponent = styled . div . withConfig ( { displayName : 'StyledComponent' } ) `
color: red;
` ;巢規則塊可創建更複雜的選擇器。
const StyledComponent = styled ( 'div' ) `
.child {
color: blue;
.grandchild {
color: green;
}
}
` ;就像樣式的動態類被預選到頂級選擇器一樣,父母選擇器也被培養給子女選擇器。
. _rmsds7y13d_ . child {
color : blue;
}
. _rmsds7y13d_ . child . grandchild {
color : green;
}家長選擇器參考( & )的工作方式與SCS/SASS中的方式相同。一個額外的細節是,當在樣式根上使用父級選擇器(不嵌套在父塊內)時,它是指當前樣式的唯一樣式類,即該樣式的隱式/虛擬父塊選擇器。
const StyledComponent = styled ( 'div' ) `
&& {
color: red;
}
&:hover {
color: blue;
}
.parent & {
color: green;
}
` ;支持所有CSS ATULES( @charset除外, <style>元素中不允許使用)。
const StyledComponent = styled ( 'div' ) `
@media screen and (min-width: 900px) {
color: red;
}
.child {
@media screen and (min-width: 600px) {
.grandchild {
color: blue;
.adopted & {
color: green;
}
}
}
}
` ;在必要的情況下,將懸掛在符號的情況下,而在沒有介入設備的情況下,將以相同的方式處理家長的選擇者。
@media screen and ( min-width : 900 px ) {
. _rmsds7y13d_ {
color : red;
}
}
@media screen and ( min-width : 600 px ) {
. _rmsds7y13d_ . child . grandchild {
color : blue;
}
. adopted . _rmsds7y13d_ . child . grandchild {
color : green;
}
}如果CSS屬性值為“空”(空字符串, false , null , undefined或"" ),則將從樣式中省略整個屬性。
const StyledComponent = styled ( 'div' ) `
color: ${ null } ;
background-color: red;
` ;不包括顏色屬性,因為它沒有價值。
. _rmsds7y13d_ {
background-color : red;
}樣式可以包含塊( /* */ )和行註釋( // )。評論永遠不會包含在渲染樣式表中。
const StyledComponent = styled ( 'div' ) `
// This is a comment.
/* And so...
...is this. */
` ; styled.string標記的模板函數返回一個簡單的樣式字符串,其中所有值插值。僅允許靜態值(無函數)。空屬性值( null , undefined , false和"" )以相同的方式在樣式組件中使用,並導致屬性被省略。
const fontHelper = styled . string `
font-family: Arial, sans-serif;
font-weight: 400;
font-size: ${ size } ;
` ;
// Then use in a styled component or another helper.
const StyledComponent = styled ( 'div' ) `
${ fontHelper }
color: red;
` ; styled.string手沒有副作用,而且工作很少,因此在功能中也可以安全使用。
const shadow = ( depth : number ) => {
return styled . string `
-moz-box-shadow: 0 ${ depth } px ${ depth } px black;
-webkit-box-shadow: 0 ${ depth } px ${ depth } px black;
box-shadow: 0 ${ depth } px ${ depth } px black;
` ;
} ;
// Then use in a styled component or another helper.
const StyledComponent = styled ( 'div' ) < { $shadowDepth : number } > `
${ ( props ) => shadow ( props . $shadowDepth ) }
color: red;
` ; 使用StyledTest包裝器生產具有穩定的類名稱和样式信息的快照。
const container = render ( < MyStyledComponent /> , { wrapper : StyledTest } ) ;
expect ( container ) . toMatchSnapshot ( ) ; // Snapshot
<div>
<div
class="_test-dynamic-0_ _test-static-0_"
>
Hello, world!
</div>
<style>
._test-dynamic-0_ {
padding: 1rem;
}
</style>
</div>
StyledProvider可以覆蓋默認的cache , manager和renderer 。默認操作不需要提供商。
const cache = createStyledCache ( ) ;
const manager = createStyledManager ( ) ;
const renderer = createStyledRenderer ( ) ;
render (
< StyledProvider cache = { cache } manager = { manager } renderer = { renderer } >
< App />
</ StyledProvider > ,
) ; StyledTest組件是一種預先配置的StyledProvider ,它注入了所有三個資源的測試版本以替換班級名稱並捕獲樣式。
注意:提供的緩存,管理器和渲染器不得在樣式組件的壽命中更改。如果發生突變,將拋出(或在生產中記錄)。
在呈現服務器上的應用程序時,請使用createSsrStyledManager和StyledProvider捕獲樣式。
const manager = createSsrStyledManager ( ) ;
const html = renderToString (
< StyledProvider manager = { manager } >
< App />
</ StyledProvider > ,
) ;
const html = `
<!doctype HTML>
<html>
<head>
${ manager . getStyleTags ( ) }
</head>
<body>
<div id="root">
${ html }
</div>
</body>
</html>
` ; SSR Manager的getStyleTags()方法返回一個僅包含<style>標籤的單個HTML字符串。還有getStyleElement() (react元素數組)和getCss() (CSS字符串數組)方法。
使用createStyledManager (或createSsrStyledManager )和StyledProvider對所有註射樣式設置nonce 。
const manager = createStyledManager ( nonce ) ;
render (
< StyledProvider manager = { manager } >
< App />
</ StyledProvider > ,
) ; | 特徵 | Minstack風格 | 戈貝 | 樣式的組件 | 情感 | |
|---|---|---|---|---|---|
| 圖書館 | |||||
| 束大小(大約KB)[1] | 2.8 | 1.2 | 13.3 | 9.1 | |
| 零依賴性 | ? | ? | ? | ? | |
| 打字稿本地 | ? | ? | ? | ? | |
| API | |||||
| 標記的模板樣式 | ? | ? | ? | ? | |
| 動態風格 | ? | ? | ? | ? | |
| 對像樣式 | ? | ? | ? | ? | |
| 全球風格 | ? | ? | ? | ? | |
多態性( as ) | ? | ? | ? | ? | |
屬性映射( attrs ) | ? | ? | ? | ? | |
| 主題[2] | ? | ? | ? | ? | |
| SSR | ? | ? | ? | ? | |
| 快照測試 | ? | ? | ? | ? | |
| 風格 | |||||
| 基本CSS語法[3] | ? | ? | ? | ? | |
CSS @media | ? | ? | ? | ? | |
CSS @keyframes | ? | ? | ? | ? | |
CSS @font-face | ? | ⭕ | ⭕ | ? | |
CSS @import | ? | ⭕ | ? | ? | |
其他CSS @規則 | ? | ⭕ | ⭕ | ⭕ | |
| 供應商前綴[4] | ? | ? | ? | ? | |
| 規則嵌套 | ? | ? | ? | ? | |
家長選擇器( & ) | ? | ? | ? | ? | |
| 樣式的組件選擇器[5] | ? | ? | ? | ? |
styled導出(搖晃,縮小和GZIP之後)。 Goober與此解決方案非常相似。它快速,較小,並且支持一些額外的功能(對像樣式和as屬性)。那麼,Goober的缺點是什麼,為什麼要使用它?
StyledTest測試包裝組件,不僅可以進行快照測試,而且以測試框架不可知的方式進行。setup()函數,這不會更改主題類型。通過聲明合併可以擴展主題類型,但這再次是全局,不是很安全。該庫提供了返回一個新的API實例的createStyled()工廠,該實例具有強烈的主題。styled.div而不是styled('div') )。該庫支持styled.<tag>沒有編譯時間支持。setup()進行調用。該庫的目標是反應,並且在使用preact時需要preact/compat 。該圖書館被認為是景點支持的一些功能。這是為了減少可以設計樣式組件的替代方法,從而提高了代碼一致性,並提供了更好的開發人員體驗(DX)。刪除對完成同一操作的兩種不同方法的支持也意味著庫的大小和運行時開銷將減少和/或分配到改進的核心功能,並且庫的總體上更可維護。
as屬性,用於更改樣式組件的基礎組件類型。該庫並不是因為它固有地鍵入不安全,並且使用樣式助手(例如, styled.string實用程序)提供了一種更好的重複使用樣式的方法。有關基準實現,請參見Benchmark.js腳本。
| 圖書館 | OP/s |
|---|---|
| Minstack風格 | 144,970 |
| 戈貝 | 142,028 |
| 情感 | 124,681 |
| 樣式的組件 | 118,072 |
getId接受可選的名稱空間參數(重新添加).withConfig()靜態方法為樣式模板getId和動態類哈希中使用主要版本styled.div styled('div') )useInsertionEffectstyled.stringStyledProvidercreateSsrStyledManager )StyledTest )getId不再接受論點styled.mixin混合renderStylesToString