サーバー側のレンダリング、ブラウザープレフィックス、および最小CSS生成をサポートするフレームワークに依存しないCSS-in-JS。
JavaScriptコンポーネントでスタイルをコロッキングするためのサポート。
:hover
、 :active
などのような擬似選択因子をサポートします。ホバーまたはアクティブ状態をコンポーネントに保存する必要はありません。 :visited
仕事もうまくいきました。@font-face
検出と挿入をサポートします。AphroditeはNPMを介して配布されます。
npm install --save aphrodite
紹介ビデオを視聴したい場合は、ここで見つけることができます。
import React , { Component } from 'react' ;
import { StyleSheet , css } from 'aphrodite' ;
class App extends Component {
render ( ) {
return < div >
< span className = { css ( styles . red ) } >
This is red.
< / span >
< span className = { css ( styles . hover ) } >
This turns red on hover.
< / span >
< span className = { css ( styles . small ) } >
This turns red when the browser is less than 600px width.
< / span >
< span className = { css ( styles . red , styles . blue ) } >
This is blue.
< / span >
< span className = { css ( styles . blue , styles . small ) } >
This is blue and turns red when the browser is less than
600px width.
< / span >
< / div > ;
}
}
const styles = StyleSheet . create ( {
red : {
backgroundColor : 'red'
} ,
blue : {
backgroundColor : 'blue'
} ,
hover : {
':hover' : {
backgroundColor : 'red'
}
} ,
small : {
'@media (max-width: 600px)' : {
backgroundColor : 'red' ,
}
}
} ) ;
注:条件付きスタイルを使用したい場合は、次のことを単純に達成します。
const className = css (
shouldBeRed ( ) ? styles . red : styles . blue ,
shouldBeResponsive ( ) && styles . small ,
shouldBeHoverable ( ) && styles . hover
)
< div className = { className } > Hi < / div>
これは、偽の議論が無視されるため可能です。
スタイルを組み合わせるには、複数のスタイルまたはスタイルの配列をcss()
に渡します。これは、所有者コンポーネントのスタイルを組み合わせるときに一般的です。
class App extends Component {
render ( ) {
return < Marker styles = { [ styles . large , styles . red ] } / > ;
}
}
class Marker extends Component {
render ( ) {
// css() accepts styles, arrays of styles (including nested arrays),
// and falsy values including undefined.
return < div className = { css ( styles . marker , this . props . styles ) } / > ;
}
}
const styles = StyleSheet . create ( {
red : {
backgroundColor : 'red'
} ,
large : {
height : 20 ,
width : 20
} ,
marker : {
backgroundColor : 'blue'
}
} ) ;
reset
機能を使用して、HTMLスタイルのタグ、噴射バッファー、および注入キャッシュをリセットできます。 Aphroditeを取り壊して戻ってくる必要がある場合に役立ちます。
import { reset } from 'aphrodite' ;
reset ( ) ;
一方、 resetInjectedStyle
関数を使用して、注入されたキャッシュを単一のキー(通常はクラス名)にリセットできます。
import { resetInjectedStyle } from 'aphrodite' ;
resetInjectedStyle ( 'class_1sAs8jg' ) ;
サーバー側のレンダリングを実行するには、 StyleSheetServer.renderStatic
を呼び出します。これにより、コールバックが必要です。コールバック内でレンダリングを行い、生成されたHTMLを返します。コールバック内のcss()
への呼び出しはすべて収集され、生成されたCSSと生成されたHTMLが返されます。
再水和では、Aphroditeがページに既に挿入されているスタイルを知ることができます。水分補給がなければ、アフロディーテはページに重複スタイルを追加する可能性があります。
再水分化を実行するには、 StyleSheetServer.renderStatic
によってあなたに返された生成されたクラス名のリストを使用して、 StyleSheet.rehydrate
呼び出します。
注:プロジェクトでaphrodite/no-important
に使用していて、サーバー側でレンダリングする場合は、 aphrodite/no-important
からStyleSheetServer
インポートしてください。そうしないと、エラーが発生します。
例として:
import { StyleSheetServer } from 'aphrodite' ;
// Contains the generated html, as well as the generated css and some
// rehydration data.
var { html , css } = StyleSheetServer . renderStatic ( ( ) => {
return ReactDOMServer . renderToString ( < App / > ) ;
} ) ;
// Return the base HTML, which contains your rendered HTML as well as a
// simple rehydration script.
return `
<html>
<head>
<style data-aphrodite> ${ css . content } </style>
</head>
<body>
<div id='root'> ${ html } </div>
<script src="./bundle.js"></script>
<script>
StyleSheet.rehydrate( ${ JSON . stringify ( css . renderedClassNames ) } );
ReactDOM.render(<App/>, document.getElementById('root'));
</script>
</body>
</html>
` ;
!important
デフォルトでは、アフロディーテはスタイル定義に!important
。これは、既存のコードベースとの統合をより簡単にすることを目的としています。この動作を回避したい場合は、 aphrodite
をインポートする代わりに、 aphrodite/no-important
インポートを輸入してください。それ以外の場合、使用法は同じです。
import { StyleSheet , css } from 'aphrodite/no-important' ;
デフォルトでは、Aphroditeはスタイル名を生産中にハッシュに縮小します( process.env.NODE_ENV === 'production'
)。 StyleSheet.create
を呼び出す前に、 minify
true
またはfalse
で呼び出すことにより、この動作をオーバーライドできます。
これは、たとえば生産でのデバッグを容易にしたい場合に役立ちます。
import { StyleSheet , minify } from 'aphrodite' ;
// Always keep the full style names
minify ( false ) ;
// ... proceed to use StyleSheet.create etc.
カスタムフォントフェイスの作成は特別なケースです。通常、グローバル@font-face
ルールを定義する必要があります。アフロディーテの場合、ページにあるクラスが実際に参照されている場合にのみ、そのルールを挿入したいと思います。 fontFamily
プロパティがFont-Faceオブジェクト(直接または配列内)を受け入れることができるようにしました。フォント定義に基づいて、グローバル@font-face
ルールが生成されます。
const coolFont = {
fontFamily : "CoolFont" ,
fontStyle : "normal" ,
fontWeight : "normal" ,
src : "url('coolfont.woff2') format('woff2')"
} ;
const styles = StyleSheet . create ( {
headingText : {
fontFamily : coolFont ,
fontSize : 20
} ,
bodyText : {
fontFamily : [ coolFont , "sans-serif" ]
fontSize : 12
}
} ) ;
Aphroditeは、このフォントのGlobal @font-face
ルールが、何回参照されても、一度だけ挿入されることを保証します。
Font Facesと同様に、AphroditeはKeyframeアニメーションをサポートしていますが、特別なケースとして扱われます。参照されているアニメーションのインスタンスを見つけると、グローバル@keyframes
ルールが作成され、ページに追加されます。
アニメーションは、典型的な@keyframes
のファッションで、アニメーションを説明するオブジェクトとして提供されます。 animationName
プロパティを使用して、単一のアニメーションオブジェクト、またはアニメーションオブジェクトの配列を提供できます。 animationDuration
などの他のアニメーションプロパティは、文字列として提供できます。
const translateKeyframes = {
'0%' : {
transform : 'translateX(0)' ,
} ,
'50%' : {
transform : 'translateX(100px)' ,
} ,
'100%' : {
transform : 'translateX(0)' ,
} ,
} ;
const opacityKeyframes = {
'from' : {
opacity : 0 ,
} ,
'to' : {
opacity : 1 ,
}
} ;
const styles = StyleSheet . create ( {
zippyHeader : {
animationName : [ translateKeyframes , opacityKeyframes ] ,
animationDuration : '3s, 1200ms' ,
animationIterationCount : 'infinite' ,
} ,
} ) ;
Aphroditeは、特定のルールが何回参照されていても、 @keyframes
ルールが複製されないことを保証します。
アフロディーテは反応を念頭に置いて構築されましたが、反応に依存しません。ここでは、Webコンポーネントで使用されていることがわかります。
import { StyleSheet , css } from 'aphrodite' ;
const styles = StyleSheet . create ( {
red : {
backgroundColor : 'red'
}
} ) ;
class App extends HTMLElement {
attachedCallback ( ) {
this . innerHTML = `
<div class=" ${ css ( styles . red ) } ">
This is red.
</div>
` ;
}
}
document . registerElement ( 'my-app' , App ) ;
Aphroditeは、ドキュメントの<head>
要素に<style>
タグを自動的に作成して、生成されたスタイルを入れます。Aphroditeは1つの<style>
タグのみを生成し、時間の経過とともに新しいスタイルを追加します。 Aphroditeが使用するスタイルタグを制御する場合は、 data-aphrodite
属性を使用してスタイルタグを作成し、Aphroditeはそれを使用する代わりに使用します。
スタイルの注入をスピードアップするために、Aphroditeは自動的にこの<style>
タグに書き込みをバッファリングしようとするため、最小数のDOM修正が行われます。
Aphroditeはできるだけ早く使用してバッファフラッシュをスケジュールします。 componentDidMount
またはcomponentDidUpdate
でDOM要素の寸法を測定する場合、 setTimeout
またはflushToStyleTag
を使用して、すべてのスタイルが注入されていることを確認できます。
import { StyleSheet , css } from 'aphrodite' ;
class Component extends React . Component {
render ( ) {
return < div ref = "root" className = { css ( styles . div ) } / > ;
}
componentDidMount ( ) {
// At this point styles might not be injected yet.
this . refs . root . offsetHeight ; // 0 or 10
setTimeout ( ( ) => {
this . refs . root . offsetHeight ; // 10
} , 0 ) ;
}
}
const styles = StyleSheet . create ( {
div : {
height : 10 ,
} ,
} ) ;
文字列をcontent
プロパティに割り当てるときは、CSSで二重または単一の引用符が必要です。したがって、Aphroditeを使用すると、CSSで表現する方法と一致するように、 content
の値文字列内の引用符も提供する必要があります。
例として:
const styles = StyleSheet . create ( {
large : {
':after' : {
content : '"Aphrodite"' ,
} ,
} ,
} ,
small : {
':before' : {
content : "'Aphrodite'" ,
} ,
} ,
} ) ;
生成されたCSSは次のとおりです。
. large_im3wl1 : after {
content : "Aphrodite" !important ;
}
. small_ffd5jf : before {
content : 'Aphrodite' !important ;
}
複数のアフロディーテスタイルを組み合わせる場合、すべてのスタイルをcss()
への単一の呼び出しに統合することを強くお勧めします。また、アフロディーテ出力が生成されたクラス名を組み合わせるべきではありません(文字列コンカテネーション、 classnames
など)。たとえば、 bar
でオーバーライドしようとしているfoo
のベーススタイルがある場合:
const styles = StyleSheet . create ( {
foo : {
color : 'red'
} ,
bar : {
color : 'blue'
}
} ) ;
// ...
const className = css ( styles . foo , styles . bar ) ;
const styles = StyleSheet . create ( {
foo : {
color : 'red'
} ,
bar : {
color : 'blue'
}
} ) ;
// ...
const className = css ( styles . foo ) + " " + css ( styles . bar ) ;
なぜそれが重要なのですか? 2つ目は有効なクラス名を作成しますが、 bar
スタイルがfoo
スタイルをオーバーライドすることを保証することはできません。 CSSの動作方法は、重要な要素で最後になるのはクラス名ではなく、特異性です。生成されたCSSを見ると、すべてのクラス名が同じ特異性を持っていることがわかります。それらはすべて単一のクラス名であるためです。
. foo_im3wl1 {
color : red;
}
. bar_hxfs3d {
color : blue;
}
特異性が同じ場合、重要なのは、スタイルシートにスタイルが表示される順序です。つまり、生成されたスタイルシートがどのように見えるかです
. foo_im3wl1 {
color : red;
}
. bar_hxfs3d {
color : blue;
}
その後、あなたはfoo
ものを上書きするbar
スタイルの適切な効果を得るでしょうが、スタイルシートが次のように見える場合
. bar_hxfs3d {
color : blue;
}
. foo_im3wl1 {
color : red;
}
その後、 foo
Overriding bar
で、反対の効果があります!これを解決する方法は、両方のスタイルをAphroditeのcss()
呼び出しに渡すことです。次に、 foo_im3wl1-o_O-bar_hxfs3d
のような単一のクラス名を作成し、正しくオーバーライドされたスタイルを使用して、問題を解決します。
. foo_im3wl1-o_O-bar_hxfs3d {
color : blue;
}
スタイルがアフロディーテで指定されている場合、実際のスタイルシートに表示される順序は、キーがオブジェクトから取得される順序によって異なります。この順序は、スタイルをレンダリングするために使用されているJavaScriptエンジンによって決定されます。時々、スタイルがCSSのセマンティクスのスタイルシートの問題に表示される順序。たとえば、エンジンに応じて、から生成されたスタイル
const styles = StyleSheet . create ( {
ordered : {
margin : 0 ,
marginLeft : 15 ,
} ,
} ) ;
css ( styles . ordered ) ;
次のCSSが生成されると予想される場合があります。
margin : 0 px ;
margin-left : 15 px ;
ただし、スタイルオブジェクトのキーの順序に応じて、CSSは次のように表示される場合があります
margin-left : 15 px ;
margin : 0 px ;
これは意味的に異なります。なぜなら、後で表示されるスタイルは、その前にスタイルを無効にするからです。
これは、生成されたスタイルがクライアントとサーバーに異なる順序で表示される場合、サーバー側のレンダリングの場合に問題として現れる可能性があります。
生成されたCSSにスタイルがオブジェクトに表示される順に表示されないこの問題が発生した場合、2つの解決策があります。
速記のプロパティを使用しないでください。たとえば、上記のマージンの例では、同じスタイルの速記プロパティとロングハンドプロパティの使用から、ロングハンドプロパティのみを使用することに切り替えることにより、問題は回避できます。
const styles = StyleSheet . create ( {
ordered : {
marginTop : 0 ,
marginRight : 0 ,
marginBottom : 0 ,
marginLeft : 15 ,
} ,
} ) ;
Map
使用してそれらを指定して、スタイルの順序を指定します。 Map
Sは挿入順序を保持するため、Aphroditeはスタイルを正しい順序で配置できます。
const styles = StyleSheet . create ( {
ordered : new Map ( [
[ "margin" , 0 ] ,
[ "marginLeft" , 15 ] ,
] ) ,
} ) ;
Map
Sはすべてのブラウザで完全にサポートされていないことに注意してください。 ES6-Shimのようなパッケージを使用してポリフィルできます。
拡張機能を使用して、アフロディーテに追加機能を追加できます。
aphroditeに拡張機能を追加するには、追加する拡張機能でStyleSheet.extend
を呼び出します。結果は、拡張機能を含むアフロディーテ( css
、 StyleSheet
など)の通常のエクスポートを含むオブジェクトになります。例えば:
// my-aphrodite.js
import { StyleSheet } from "aphrodite" ;
export default StyleSheet . extend ( [ extension1 , extension2 ] ) ;
// styled.js
import { StyleSheet , css } from "my-aphrodite.js" ;
const styles = StyleSheet . create ( {
...
} ) ;
注:拡張機能を使用すると、Aphroditeのスタイルが適切に機能しない場合があります。プレーンアフロディーテは、適切に使用すると、正しいスタイルが常に要素に適用されるようにします。 CSS特異性ルールにより、拡張機能により、互いに競合するスタイルを生成し、誤ったスタイルを表示することができます。何がうまくいかないかを確認するには、以下のグローバル拡張機能を参照してください。
現在、利用可能な拡張機能の種類は1つだけです。セレクターハンドラーです。これらの種類の拡張機能を使用すると、誰かが指定し、それらに基づいて新しいセレクターを生成するセレクターを調べることができます。それらは、アフロディーテ内の擬似スタイルとメディアクエリを処理するために使用されます。セレクターハンドラー関数を作成する方法については、 defaultSelectorHandlers
ドキュメントを参照してください。
拡張機能を使用するには、作成した拡張機能の種類のキーを含むオブジェクトを作成し、それをStyleSheet.extend()
に渡します。
const mySelectorHandler = ... ;
const myExtension = { selectorHandler : mySelectorHandler } ;
const { StyleSheet : newStyleSheet , css : newCss } = StyleSheet . extend ( [ myExtension ] ) ;
例として、次のようなグローバルスタイルを生成する拡張機能を作成できます
const globalSelectorHandler = ( selector , _ , generateSubtreeStyles ) => {
if ( selector [ 0 ] !== "*" ) {
return null ;
}
return generateSubtreeStyles ( selector . slice ( 1 ) ) ;
} ;
const globalExtension = { selectorHandler : globalSelectorHandler } ;
ただし、2つの場所が同じグローバルセレクターのスタイルを生成しようとすると問題を引き起こす可能性があります。たとえば、後
const styles = StyleSheet . create ( {
globals : {
'*div' : {
color : 'red' ,
} ,
}
} ) ;
const styles2 = StyleSheet . create ( {
globals : {
'*div' : {
color : 'blue' ,
} ,
} ,
} ) ;
css ( styles . globals ) ;
css ( styles2 . globals ) ;
Divが赤か青かを決定するものではありません。
環境変数process.env.NODE_ENV
文字列値のproduction
に設定して、クラス名をマイニーします。
StyleSheet.create
に渡すものを貼り付けて、生成されたCSSを表示しますCopyright(c)2016 Khan Academy