서버 측 렌더링, 브라우저 접두사 및 최소 CSS 생성을 지원하는 프레임 워크 공유 CSS-in-JS.
JavaScript 구성 요소와 함께 스타일을 통합하는 지원.
:hover
, :active
등을 구성 요소에 저장할 필요없이 다음과 같은 의사 선택자를 지원합니다. :visited
도 잘 작동합니다.@font-face
감지 및 삽입을 지원합니다.아프로디테는 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 스타일 태그, 분사 버퍼 및 주입 된 캐시를 재설정하는 데 사용될 수 있습니다. 아프로디테가 찢어지고 백업해야 할 때 유용합니다.
import { reset } from 'aphrodite' ;
reset ( ) ;
resetInjectedStyle
함수는 단일 키 (일반적으로 클래스 이름)에 대해 주입 된 캐시를 재설정하는 데 사용될 수 있습니다.
import { resetInjectedStyle } from 'aphrodite' ;
resetInjectedStyle ( 'class_1sAs8jg' ) ;
서버 측 렌더링을 수행하려면 StyleSheetServer.renderStatic
호출하여 콜백을합니다. 콜백 내부에서 렌더링을 수행하고 생성 된 HTML을 반환하십시오. 콜백 내부의 css()
에 대한 모든 통화가 수집되고 생성 된 CSS 및 생성 된 HTML이 반환됩니다.
재수 화하면 아프로디테에게 어떤 스타일이 이미 페이지에 삽입되었는지 알려줍니다. 재수 화되지 않으면 아프로디테는 페이지에 중복 스타일을 추가 할 수 있습니다.
재수 화를 수행하려면 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
기본적으로 Aphrodite는 스타일 정의에 !important
. 이것은 기존 코드베이스와 쉽게 통합하기위한 것입니다. 이 동작을 피하려면 aphrodite
가져 오는 대신 aphrodite/no-important
수입. 그렇지 않으면 사용법이 동일합니다.
import { StyleSheet , css } from 'aphrodite/no-important' ;
기본적으로 Aphrodite는 스타일 이름을 생산에서 해시까지 미리 적용합니다 ( process.env.NODE_ENV === 'production'
). StyleSheet.create
호출하기 전에 true
또는 false
로 minify
호출 하여이 동작을 무시할 수 있습니다.
예를 들어 프로덕션에서 디버깅을 용이하게하려는 경우 유용합니다.
import { StyleSheet , minify } from 'aphrodite' ;
// Always keep the full style names
minify ( false ) ;
// ... proceed to use StyleSheet.create etc.
맞춤형 글꼴 얼굴을 만드는 것은 특별한 경우입니다. 일반적으로 Global @font-face
규칙을 정의해야합니다. 아프로디테의 경우 실제로 페이지에있는 클래스에서 실제로 참조되는 경우 해당 규칙을 삽입하려고합니다. fontFamily
속성이 글꼴 면전 객체 (직접 또는 어레이 내부)를 수용 할 수 있도록했습니다. 그런 다음 글로벌 @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는 키 프레임 애니메이션을 지원하지만 특별한 경우로 취급됩니다. 애니메이션 인스턴스가 참조되는 인스턴스를 찾으면 Global @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
규칙이 복제되지 않도록합니다.
Aphrodite는 React를 염두에두고 구축되었지만 React에 의존하지 않습니다. 여기에서는 웹 구성 요소와 함께 사용되는 것을 볼 수 있습니다.
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는 하나의 <style>
태그 만 생성하고 시간이 지남에 따라 새로운 스타일을 추가합니다. 어떤 스타일 태그 아프로디테가 사용하는지 제어하려면 data-aphrodite
속성으로 스타일 태그를 만들면 Aphrodite가 당신을 위해 하나를 만드는 대신 그것을 사용할 것입니다.
스타일의 주입 속도를 높이기 위해 Aphrodite는 자동 으로이 <style>
태그에 쓰기를 자동으로 시도하여 최소의 DOM 수정이 발생합니다.
아프로디테는 최대한 빨리 버퍼 플러싱을 예약합니다. 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
등)을 결합해서는 안됩니다. 예를 들어, 기본 스타일의 foo
있는 경우 bar
함께 무시하려고합니다.
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 ) ;
왜 중요한가? 두 번째는 유효한 클래스 이름을 생성하지만 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
Orediding bar
와 함께 반대 효과로 끝납니다! 이것을 해결하는 방법은 두 스타일을 모두 Aphrodite의 css()
호출로 전달하는 것입니다. 그런 다음 foo_im3wl1-o_O-bar_hxfs3d
와 같은 단일 클래스 이름을 생성하고 올바르게 재정의 된 스타일을 사용하여 문제를 해결합니다.
. foo_im3wl1-o_O-bar_hxfs3d {
color : blue;
}
Aphrodite에 스타일이 지정되면 실제 스타일에 나타나는 순서는 키가 객체에서 검색되는 순서에 따라 다릅니다. 이 순서는 스타일을 렌더링하는 데 사용되는 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 ;
나중에 나타나는 스타일이 이전의 스타일을 무시하기 때문에 의미 적으로 다릅니다.
생성 된 스타일이 클라이언트와 서버에 다른 순서로 나타나는 경우 서버 측 렌더링이 문제로 나타날 수도 있습니다.
생성 된 CS에 스타일이 나타나지 않는이 문제가 객체에 나타나는 순서 대로이 문제를 경험하면 두 가지 해결책이 있습니다.
속성 속성을 사용하지 마십시오. 예를 들어, 위의 여백 예제에서, 동일한 스타일의 속성 속성과 반 분산 속성을 사용하여 동일한 스타일 만 사용하는 것부터 전환하여 문제를 피할 수 있습니다.
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 ( {
...
} ) ;
참고 : 연장을 사용하면 아프로디테의 스타일이 제대로 작동하지 않을 수 있습니다. 일반 아프로디테는 올바르게 사용될 때 올바른 스타일이 항상 요소에 적용되도록합니다. CSS 특이성 규칙으로 인해 확장자를 사용하면 서로 충돌하는 스타일을 생성하여 잘못된 스타일을 표시 할 수 있습니다. 무엇이 잘못 될 수 있는지 확인하려면 아래의 글로벌 확장자를 참조하십시오.
현재 사용 가능한 확장 기능은 하나뿐입니다 : 선택기 핸들러. 이러한 종류의 확장을 통해 누군가가 그들을 기반으로 새로운 선택기를 지정하고 생성하는 선택기를 살펴볼 수 있습니다. 그들은 아프로디테 내부의 의사 스타일과 미디어 쿼리를 처리하는 데 사용됩니다. 선택기 핸들러 기능을 만드는 방법에 대한 정보는 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 } ;
그러나 두 곳이 동일한 글로벌 선택기를 위해 스타일을 생성하려고 할 때 문제가 발생할 수 있습니다! 예를 들어, 후
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
설정하여 클래스 이름을 최소화하십시오 .env.node_env를 문자열 값 production
으로 설정하십시오.
StyleSheet.create
에 전달한 것을 붙여 넣습니다. 생성 된 CSS를 만듭니다.저작권 (C) 2016 칸 아카데미