
ã€ã³ã¿ãŒãããã®æŽå²ã®æåããããµã€ãã®ã¹ã¿ã€ã«ãå¿
èŠã§ããã é·å¹Žã«ããããç¬èªã®ããŒã¹ã§éçºãããCSSããã®ããã«åœ¹ç«ã¡ãŸããã ãããŠãããã§ãã®éçºã®æŽå²ãèŠãŠãããŸãã
ç§ã¯èª°ãããã®å®çŸ©ã«åæãããšæãïŒCSSã¯
ããŒã¯ã¢ããèšèªã§æžãã
ãããã¥ã¡ã³ãã®
ãã¬ãŒã³ããŒã·ã§ã³ãèšè¿°ããããã«äœ¿çšãã
ãŸã ã ãŸããCSSãé·å¹Žã«ããã£ãŠããªã匷åãªããŒã«ã«ãªããããŒã ã䜿çšããããã«è¿œå ã®ããŒã«ãå¿
èŠã§ããããšã誰ã«ãšã£ãŠããã¥ãŒã¹ã§ã¯ãããŸããã
ã¯ã€ã«ãCSS
1990幎代ãç§ãã¡ã¯ãçŽ æŽããããã€ã³ã¿ãŒãã§ã€ã¹ãäœæããã®ã奜ãã§ããããããèŠçŽ ãæãéèŠã§ããã åœæã¯ã€ã³ã©ã€ã³ã¹ã¿ã€ã«ãéèŠãããŠããŸããããããŒãžã®èŠçŽ ãç°ãªã£ãŠèŠãããã©ããã¯æ°ã«ããŸããã§ããã WebããŒãžã¯ããããããã¡ãã§ãã¯ãŒã«ãªgifãå¿ã³å¯ãã©ã€ã³ããã®ä»ã®æªå€¢ã®ãããªïŒãããå°è±¡çãªïŒèŠçŽ ã§é£œåãã蚪åè
ã®æ³šæãåŒãä»ããããšããŸããã
ãã®åŸãåçãµã€ãã®äœæãéå§ããŸããããCSSã¯ç¡æ³ã®èŠå¡ã®ãŸãŸã§ãããåéçºè
ã¯ãCSSã®äœææ¹æ³ã«ã€ããŠç¬èªã®ã¢ã€ãã¢ãæã£ãŠããŸããã 誰ãã
ç¹ç°æ§ã«èŠåŽããæ°ããã³ãŒããç»å ŽãããšèŠèŠçãªéè¡ã«ã€ãªãããŸããã
éèŠãªã®ã¯ãã€ã³ã¿ãŒãã§ã€ã¹èŠçŽ ãç¹å®ã®æ¹æ³ã§èŠããããã«ãç³ã«æå¿ã®ã·ã³ãã«ã圫ããããšããããšã§ãã ããããããã«æ°ä»ããŸããïŒ
ãããžã§ã¯ãã®èŠæš¡ãšè€éããå¢ããéçºããŒã ãæé·ããã«ã€ããŠããããã®ææ³ã¯ãã¹ãŠããŸããŸãæçœã§å€§ããªåé¡ã«å€ãããŸããã ãããã£ãŠãã¹ã¿ã€ã«ã®é©çšã«ããã
ãã¿ãŒã³ã®æ¬ åŠã¯ãCSSã䜿çšããæ£ããæ¹æ³ãèŠã€ããããšããŠããçµéšè±å¯ã§çµéšã®æµ
ãéçºè
ã«ãšã£ãŠäž»èŠãªé害ã®1ã€ã«ãªããŸããã æçµçã«ãæ£ããæ¹æ³ãšééã£ãæ¹æ³ããªãããšã«æ°ä»ããŸããã ç§ãã¡ã¯ãã¹ãŠããŸãšãã«èŠããããã«ããããšããŸããã
SASSã«ããæå©
SASSã¯CSSãã
ãã¹ãã倿°ãããã¯ã¹ã€ã³ãæ¡åŒµãããžãã¯ãã¹ã¿ã€ã«ã·ãŒãã«å®è£
ããååŠçãšã³ãžã³ãšããŠæç€ºããããé©åãªããã°ã©ãã³ã°èšèªã«å€ããŸããã ãã®ãããCSSãã¡ã€ã«ãããé©åã«æŽçã§ããŸãããŸããCSSã³ãŒãã®å€§ããªéšåãå°ããªãã¡ã€ã«ã«åè§£ããæ¹æ³ãããã€ããããŸãã åœæãããã¯å€§ããªé©æ°ã§ããã
ååã¯æ¬¡ã®ãšããã§ããCSSã³ãŒããååŸããŠååŠçãããã¡ã€ã«ãäžè¬çãªCSSããã±ãŒãžã«ã³ã³ãã€ã«ããŸãã ãã£ããã ããã»ã©å€ãã¯ãããŸããã ãã°ããããŠãSASSãæŠç¥ãªãã§æé«ã®æè¡ãé©çšããªããã°ãSASSã解決ãã以äžã®åé¡ãããããããšãæããã«ãªããŸããã
çªç¶ãéçºè
ã¯ããªããã»ããµãäœãããŠããã®ãã詳ãã調ã¹ãããšããããç¹å®æ§ãæã¡è² ããããã«ãã¹ãã«ãã£ãããšäŸåãå§ããŸããã ããããããã«ãããã³ã³ãã€ã«ãããã¹ã¿ã€ã«ããŒãžã®ãµã€ãºãæ¥æ¿ã«å¢å ããŸããã
BEMã衚瀺ããããŸã§...
BEMãšã³ã³ããŒãã³ãã®æŠå¿µ
BEMã¯æ°é®®ãªç©ºæ°ã®æ¯å¹ã§ããã 圌ã¯ãåå©çšæ§ãšã³ã³ããŒãã³ãã«ã€ããŠãã£ãšèããããŠãããŸããã æ¬è³ªçã«ããã®ãã¯ãããžãŒã¯ã»ãã³ãã£ã¯ã¹ãæ°ããã¬ãã«ã«åŒãäžããŸããã ããã§ãclassNameãäžæã§ãããåçŽãªBlockãElementãModifierèŠåã䜿çšããããšã§ãç¹å®ã®è¡šç€ºã®ãªã¹ã¯ã軜æžãããããšã確èªã§ããŸããã
äŸãèŠãŠã¿ãŸãããïŒ
<body class="scenery"> <section class="scenery__sky"> <div class="sky [sky--dusk / sky--daytime] [sky--foggy]"> <div class="sky__clouds"></div> <div class="sky__sun"></div> </div> </section> <section class="scenery__ground"></section> <section class="scenery__people"></section> </body>
ããŒã¯ã¢ãããåæãããšãããã«BEMå¥çŽã®ææã衚瀺ãããŸãã ã³ãŒãã«ã¯ã
.scenery
ãš
.sky
2ã€ã®æç€ºçãªãããã¯ããããŸãã ããããã«ç¬èªã®ãããã¯ããããŸãã ããšãã°ãé§ãæŒããŸãã¯å€çŒãã¯ãã¹ãŠåãèŠçŽ ã«é©çšã§ããç°ãªãç¹æ§ã§ããããã
sky
ã®ã¿ä¿®é£ŸåããããŸãã
ããè¯ãåæã®ããã«ãããã€ãã®æ¬äŒŒã³ãŒããå«ãä»éããCSSãèŠãŠãã ããïŒ
// Block .scenery { //Elements &__sky { fill: screen; } &__ground { float: bottom; } &__people { float: center; } } //Block .sky { background: dusk; // Elements &__clouds { type: distant; } &__sun { strength: .025; } // Modifiers &--dusk { background: dusk; .sky__clouds { type: distant; } .sky__sun { strength: .025; } } &--daytime { background: daylight; .sky__clouds { type: fluffy; float: center; } .sky__sun { strength: .7; align: center; float: top; } } }
BEMã®åäœãå®å
šã«çè§£ãããå Žåã¯ãå人ãååãæžã
ãèšäºãèªãããšããå§ãããŸãã
BEMã¯ãïŒreusabilityFtwåºæã®ã³ã³ããŒãã³ãã®äœæã«é©ããŠããŸãã ãã®ã¢ãããŒãã«ãããæ°ããã¹ã¿ã€ã«ãå€ãã¹ã¿ã€ã«ã·ãŒãã«å°å
¥ãããã«ã€ããŠãããã€ãã®ãã¿ãŒã³ãããæç¢ºã«ãªããŸããã
ãããåæã«ãæ°ããåé¡ãçºçããŸããïŒ
- classNameãéžæããæé ã¯éªšã®æããäœæ¥ã«ãªããŸããã
- ããããã¹ãŠã®é·ãã¯ã©ã¹åã§ãããŒã¯ã¢ããã¯è¥å€§åããŠããŸãã
- åå©çšãããã³ã«ãã€ã³ã¿ãŒãã§ã€ã¹ã®åã³ã³ããŒãã³ããæç€ºçã«å±éããå¿
èŠããããŸãã
- ããŒã¯ã¢ãããæå³çã«ãªããããŸããã
CSSã¢ãžã¥ãŒã«ãšããŒã«ã«è¡šç€ºã¹ããŒã¹
SASSãBEMãããã€ãã®åé¡ã解決ã§ããŸããã§ããã ããšãã°ãèšèªã®ããžãã¯ã«ã¯ãçã®ã«ãã»ã«åã®æŠå¿µã¯ãããŸããã ãããã£ãŠãã¯ã©ã¹åãéžæããã¿ã¹ã¯ã¯éçºè
ã«ä»»ãããŠããŸãã åé¡ã¯ãåæã§ã¯ãªãããŒã«ã®å©ããåããŠè§£æ±ºã§ãããšæããŸããã
ããã¯ãCSSã¢ãžã¥ãŒã«ãå®è¡ããããšãšãŸã£ããåãã§ããããŒã«ã«ã§å®çŸ©ãããåã¹ã¿ã€ã«ã®åçã¯ã©ã¹åã®äœæã«åºã¥ããŠããŸãã ããã«ãããæ°ããCSSããããã£ã®å°å
¥ã«ããçããèŠèŠçãªéè¡ãåãé€ãããšãã§ãããã¹ãŠã®ã¹ã¿ã€ã«ãæ£ããã«ãã»ã«åãããŸããã
CSSã¢ãžã¥ãŒã«ã¯ããã«Reactãšã³ã·ã¹ãã ã§äººæ°ãåãã仿¥ã§ã¯å€ãã®ãããžã§ã¯ãã§äœ¿çšãããŠããŸãã ãããã«ã¯é·æãšçæããããŸãããå
šäœãšããŠããã¯åªããæçšãªãã©ãã€ã ã§ãã
ãã ã...ã¢ãžã¥ãŒã«èªäœã¯äž»èŠãªCSSã®åé¡ã解決ããŸãããã¹ã¿ã€ã«å®çŸ©ãããŒã«ã©ã€ãºããæ¹æ³ã瀺ããŠããã ãã§ã
ãBEMãèªååãã
ã¹ããŒããªæ¹æ³ã§ãã¯ã©ã¹åãåŠçããå¿
èŠããªããªããŸã ïŒå°ãªããšãå°ãªãããŸãïŒã
ããããã¢ãžã¥ãŒã«ã¯ãäºæž¬å¯èœãªã¹ã¿ã€ã«ã®åªããã¢ãŒããã¯ãã£ã®å¿
èŠæ§ã軜æžãããã®ã§ã¯ãªããæ¡åŒµãšåå©çšã容æã§ããã管çã«æå°éã®åŽåããå¿
èŠãããŸããã
ããŒã«ã«CSSã¯æ¬¡ã®ããã«ãªããŸãã
@import '~tools/theme'; :local(.root) { border: 1px solid; font-family: inherit; font-size: 12px; color: inherit; background: none; cursor: pointer; display: inline-block; text-transform: uppercase; letter-spacing: 0; font-weight: 700; outline: none; position: relative; transition: all 0.3s; text-transform: uppercase; padding: 10px 20px; margin: 0; border-radius: 3px; text-align: center; } @mixin button($bg-color, $font-color) { background: $bg-color; color: $font-color; border-color: $font-color; &:focus { border-color: $font-color; background: $bg-color; color: $font-color; } &:hover { color: $font-color; background: lighten($bg-color, 20%); } &:active { background: lighten($bg-color, 30%); top: 2px; } } :local(.primary) { @include button($color-primary, $color-white) } :local(.secondary) { @include button($color-white, $color-primary) }
ããã¯åãªãCSSã§ãããäž»ãªéãã¯ã
:local
ã远å ãããã¹ãŠã®
className
ãæ¬¡ã®ãããªäžæã®ã¯ã©ã¹åãçæããããšã§ãã
.appâcomponentsâbuttonâ__root â 3vvFf {}
çæãããèå¥åã¯ãã¯ãšãªãã©ã¡ãŒã¿ãŒ
localIdentName
ã䜿çšããŠæ§æã§ããŸãã äŸïŒ
cssâloader?localIdentName=[path][name]âââ[local]âââ[hash:base64:5]
ãããã°ã容æã«ããŸãã
ããŒã«ã«CSSã¢ãžã¥ãŒã«ã¯ãåçŽãªã¢ã€ãã¢ã«åºã¥ããŠããŸãã åãååã䜿çšãããŠããå Žåã§ããä»ãšç«¶åããªãäžæã®
className
ãçæããããšã«ãããBEM衚èšãèªååããæ¹æ³ã§ãã ãšãŠã䟿å©ã§ãã
ã¹ã¿ã€ã«ä»ãã³ã³ããŒãã³ãã䜿çšããJavaScriptã«ããå®å
šãªCSSã€ã³ãžã§ã¯ã·ã§ã³
ã¹ã¿ã€ã«ä»ãã³ã³ããŒãã³ãã¯ãã©ãããŒã®ããã«æ©èœããèŠèŠçãªããªããã£ãã§ãã ãããã¯ãåã³ã³ããŒãã³ããã¹ã¿ã€ã«ä»ãã³ã³ããŒãã³ãã§ã©ããããç¹å®ã®HTMLã¿ã°ã«é¢é£ä»ããããšãã§ããŸãã
ãã®ã³ãŒãã¯ãã¢ã€ãã¢ãçè§£ããã®ã«åœ¹ç«ã¡ãŸãã
import React from "react" import styled from "styled-components"
éåžžã«ç°¡åã§ããstyled-componentsã¯ããã³ãã¬ãŒããªãã©ã«è¡šèšã䜿çšããŠCSSããããã£ãèšè¿°ããŸãã ES6ãšCSSã®æ©èœãçµã¿åãããããšã§ãéçºããŒã ãæåããããã§ãã
Styled-componentsã¯ãéåžžã«ã·ã³ãã«ã§åå©çšå¯èœãªãã¿ãŒã³ãæäŸããã€ã³ã¿ãŒãã§ã€ã¹ãæ©èœããã³æ§é ã³ã³ããŒãã³ãããå®å
šã«åé¢ããŸãã ãã©ãŠã¶ãŒã§HTMLãšããŠããŸãã¯React Nativeããã€ãã£ãã§äœ¿çšããããã€ãã£ãã¿ã°ã«ã¢ã¯ã»ã¹ã§ããAPIãäœæãããŸãã
ã«ã¹ã¿ã ããããã£ïŒãŸãã¯ä¿®é£ŸåïŒãã¹ã¿ã€ã«ä»ãã³ã³ããŒãã³ãã«æž¡ãããæ¹æ³ã¯æ¬¡ã®ãšããã§ãã
import styled from "styled-components" const Sky = styled.section` ${props => props.dusk && 'background-color: dusk' } ${props => props.day && 'background-color: white' } ${props => props.night && 'background-color: black' } `;
ã芧ã®ãšãããããããã£ã¯çªç¶åã³ã³ããŒãã³ããåãåã修食åã«ãªããç°ãªãCSSæååãååŸããããã«åŠçã§ããŸãã ããã«ãããJSã®ãã¹ãŠã®æ©èœã䜿çšããŠã¹ã¿ã€ã«ãåŠçã§ããåæã«äžè²«æ§ãä¿ãããåå©çšã®æºåãæŽããŸãã
ã¡ã€ã³ã€ã³ã¿ãŒãã§ã€ã¹ã¯èª°ã§ãåå©çšã§ããŸã
CSSã¢ãžã¥ãŒã«ãã¹ã¿ã€ã«ä»ãã³ã³ããŒãã³ãã ããçæ³çãªãœãªã¥ãŒã·ã§ã³ã§ã¯ãªãããšãããã«æããã«ãªããŸããã ããããã¹ãŠãå¹ççã«æ©èœããæ¡åŒµããã«ã¯ãç¹å®ã®ãã¿ãŒã³ãå¿
èŠã§ãã ãã®ãããªãã¿ãŒã³ã¯ãã³ã³ããŒãã³ããšã¯äœãã®å®çŸ©ãšãããžãã¯ããã®å®å
šãªåé¢ããçããŸããã ããã«ãããã¹ã¿ã€ã«ã®ã¿ãç®çãšããã³ã¢ã³ã³ããŒãã³ããäœæã§ããŸããã
CSSã¢ãžã¥ãŒã«ã䜿çšãããã®ãããªã³ã³ããŒãã³ãã®å®è£
äŸïŒ
import React from "react"; import classNames from "classnames"; import styles from "./styles"; const Button = (props) => { const { className, children, theme, tag, ...rest } = props; const CustomTag = `${tag}`; return ( <CustomTag { ...rest } className={ classNames(styles.root, theme, className) }> { children } </CustomTag> ); }; Button.theme = { secondary: styles.secondary, primary: styles.primary }; Button.defaultProps = { theme: Button.theme.primary, tag: "button" }; Button.displayName = Button.name; Button.propTypes = { theme: React.PropTypes.string, tag: React.PropTypes.string, className: React.PropTypes.string, children: React.PropTypes.oneOfType([ React.PropTypes.string, React.PropTypes.element, React.PropTypes.arrayOf(React.PropTypes.element) ]) }; export default Button;
ããã§ãã³ã³ããŒãã³ãã¯åã³ã³ããŒãã³ãã«ãã€ã³ããããããããã£ãååŸããŸãã ã€ãŸããã©ãããŒã³ã³ããŒãã³ãã¯ãã¹ãŠã®ããããã£ãåã³ã³ããŒãã³ãã«æž¡ããŸãã
ããã§ãã³ã³ããŒãã³ããæ¬¡ã®ããã«é©çšã§ããŸãã
import React from "react" import Button from "components/core/button" const = Component = () => <Button theme={ Button.theme.secondary }>Some Button</Button> export default Component
ã¹ã¿ã€ã«ä»ãã³ã³ããŒãã³ãã䜿çšããå®å
šãªãã¿ã³å®è£
ã®åæ§ã®äŸã瀺ããŸãã
import styled from "styled-components"; import { theme } from "ui"; const { color, font, radius, transition } = theme; export const Button = styled.button` background-color: ${color.ghost}; border: none; appearance: none; user-select: none; border-radius: ${radius}; color: ${color.base} cursor: pointer; display: inline-block; font-family: inherit; font-size: ${font.base}; font-weight: bold; outline: none; position: relative; text-align: center; text-transform: uppercase; transition: transorm ${transition}, opacity ${transition}; white-space: nowrap; width: ${props => props.width ? props.width : "auto"}; &:hover, &:focus { outline: none; } &:hover { color: ${color.silver}; opacity: 0.8; border-bottom: 3px solid rgba(0,0,0,0.2); } &:active { border-bottom: 1px solid rgba(0,0,0,0.2); transform: translateY(2px); opacity: 0.95; } ${props => props.disabled && ` background-color: ${color.ghost}; opacity: ${0.4}; pointer-events: none; cursor: not-allowed; `} ${props => props.primary && ` background-color: ${color.primary}; color: ${color.white}; border-color: ${color.primary}; &:hover, &:active { background-color: ${color.primary}; color: ${color.white}; } `} ${props => props.secondary && ` background-color: ${color.secondary}; color: ${color.white}; border-color: ${color.secondary}; &:hover, &:active { background-color: ${color.secondary}; color: ${color.white}; } `} `;
è峿·±ãç¹ïŒã³ã³ããŒãã³ãã¯å®å
šã«æãã§ã芪ã³ã³ããŒãã³ãã«ãã€ã³ããããCSSããããã£ã®ã©ãããŒãšããŠã®ã¿æ©èœããŸãã ãã®ã¢ãããŒãã«ã¯æ¬¡ã®å©ç¹ããããŸãã
ããã«ãããã¢ããªã±ãŒã·ã§ã³å
ã®ãã¹ãŠã®ã€ã³ã¿ãŒãã§ã€ã¹ã®äžè²«æ§ãä¿ã¡ãªãããå¿
èŠã«å¿ããŠå€æŽã§ããããŒã¹ã€ã³ã¿ãŒãã§ã€ã¹ã®APIãèšè¿°ããããšãã§ããŸãããããã£ãŠããã¶ã€ã³ã®äœæãå®è£
ããå®å
šã«åé¢ã§ããŸãã å¿
èŠã«å¿ããŠããããã¯åæã«æµããŸãã1人ã®éçºè
ãæ©èœã®å®è£
ã«åŸäºãããã1人ãã€ã³ã¿ãŒãã§ãŒã¹ãæŽç·ŽããŸããããã¯ãã¹ãŠè²¬ä»»ãå®å
šã«åé¢ããŠè¡ãããŸãã
ããã§ããã ãã®ãã¿ãŒã³ã«åŸãå¿
èŠãããããã§ãã 圌ãšäžç·ã«ãä»ã®æçšãªè§£æ±ºçãæ¢ãå§ããŸããã
äžåç£åå人
ãããã®é¢æ°ã¯ãã³ã³ããŒãã³ãã«æž¡ãããããããã£ããªãã¹ã³ããŸãã æ¬åœã«ãããããã³ã³ããŒãã³ãã®åå©çšãšæš©éä»äžã®èæ¯ã§ãã ããã¯ã修食åãç¶æ¿ããæ¹æ³ãšèŠãªãããšãã§ããŸãã ããã«ç§ãæå³ãããã®ããããŸãïŒ
// Prop passing Shorthands for Styled-components export const borderProps = props => css` ${props.borderBottom && `border-bottom: ${props.borderWidth || "1px"} solid ${color.border}`}; ${props.borderTop && `border-top: ${props.borderWidth || "1px"} solid ${color.border}`}; ${props.borderLeft && `border-left: ${props.borderWidth || "1px"} solid ${color.border}`}; ${props.borderRight && `border-right: ${props.borderWidth || "1px"} solid ${color.border}`}; `; export const marginProps = props => css` ${props.marginBottom && `margin-bottom: ${typeof (props.marginBottom) === "string" ? props.marginBottom : "1em"}`}; ${props.marginTop && `margin-top: ${typeof (props.marginTop) === "string" ? props.marginTop : "1em"}`}; ${props.marginLeft && `margin-left: ${typeof (props.marginLeft) === "string" ? props.marginLeft : "1em"}`}; ${props.marginRight && `margin-right: ${typeof (props.marginRight) === "string" ? props.marginRight : "1em"}`}; ${props.margin && `margin: ${typeof (props.margin) === "string" ? props.margin : "1em"}`}; ${props.marginVertical && ` margin-top: ${typeof (props.marginVertical) === "string" ? props.marginVertical : "1em"} margin-bottom: ${typeof (props.marginVertical) === "string" ? props.marginVertical : "1em"} `}; ${props.marginHorizontal && ` margin-left: ${typeof (props.marginHorizontal) === "string" ? props.marginHorizontal : "1em"} margin-right: ${typeof (props.marginHorizontal) === "string" ? props.marginHorizontal : "1em"} `}; `; // An example of how you can use it with your components const SomeDiv = styled.div` ${borderProps} ${marginProps} ` // This lets you pass all borderProps to the component like so: <SomeDiv borderTop borderBottom borderLeft borderRight marginVertical>
ããããã£åä¿¡è
ã®äŸããã«ãããç¹å®ã®ã³ã³ããŒãã³ãããšã«å¢çç·ãããŒãã³ãŒãã£ã³ã°ããå¿
èŠããªããªããæéã倧å¹
ã«ç¯çŽã§ããŸãã
ãã¬ãŒã¹ãã«ããŒ/ Mixinã®ãããªæ©èœ
ã¹ã¿ã€ã«ä»ãã³ã³ããŒãã³ãã§ã¯ãJSã®å¯èœæ§ãæå€§éã«æŽ»çšããŠã颿°ãããããã£ã®åãªãåä¿¡è
ã§ã¯ãªããç°ãªãã³ã³ããŒãã³ããã³ãŒããå
±æã§ããããã«ããããšãã§ããŸãã
// Mixin like functionality const textInput = props => ` color: ${props.error ? color.white : color.base}; background-color: ${props.error ? color.alert : color.white}; `; export const Input = styled.input` ${textInput} `; export const Textarea = styled.textarea` ${textInput}; height: ${props => props.height ? props.height : '130px'} resize: none; overflow: auto; `;
ã¬ã€ã¢ãŠãã³ã³ããŒãã³ã
ã¢ããªã±ãŒã·ã§ã³ã§äœæ¥ããå ŽåããŸãã€ã³ã¿ãŒãã§ãŒã¹èŠçŽ ã®ã¬ã€ã¢ãŠãã¬ã€ã¢ãŠããå¿
èŠã§ããããšãããããŸããã ãããã£ãŠããã®åé¡ã®è§£æ±ºã«åœ¹ç«ã€ã³ã³ããŒãã³ããç¹å®ããŸããã äžéšã®éçºè
ïŒCSSããžã·ã§ãã³ã°æè¡ã«ç²ŸéããŠããªãïŒã¯ãæ§é ã®äœæã«å€ãã®æéãè²»ããããšãå€ããããéåžžã«äŸ¿å©ã§ãã ãã®ãããªã³ã³ããŒãã³ãã®äŸã次ã«ç€ºããŸãã
import styled from "styled-components"; import { theme, borderProps, sizeProps, backgroundColorProps, marginProps } from "ui"; const { color, font, topbar, gutter } = theme; export const Panel = styled.article` ${marginProps} padding: 1em; background: white; color: ${color.black}; font-size: ${font.base}; font-weight: 300; ${props => !props.noborder && `border: 1px solid ${color.border}`}; width: ${props => props.width ? props.width : "100%"}; ${props => borderProps(props)} transition: transform 300ms ease-in-out, box-shadow 300ms ease-in-out, margin 300ms ease-in-out; box-shadow: 0 3px 3px rgba(0,0,0,0.1); ${props => props.dark && ` color: ${color.white}; background-color: ${color.black}; `} &:hover { transform: translateY(-5px); box-shadow: 0 6px 3px rgba(0,0,0,0.1); } `; export const ScrollView = styled.section` overflow: hidden; font-family: ${font.family}; -webkit-overflow-scrolling: touch; overflow-y: auto; ${props => props.horizontal && ` white-space: nowrap; overflow-x: auto; overflow-y: hidden; ` } ${props => sizeProps(props)} `; export const MainContent = styled(ScrollView)` position: absolute; top: ${props => props.topbar ? topbar.height : 0}; right: 0; left: 0; bottom: 0; font-size: ${font.base}; padding: ${gutter} 3em; ${props => props.bg && ` background-color: ${props.bg}; `} `; export const Slide = styled.section` ${backgroundColorProps} font-weight: 400; flex: 1; height: ${props => props.height ? props.height : "100%"}; width: ${props => props.width ? props.width : "100%"}; justify-content: center; flex-direction: column; align-items: center; text-align: center; display: flex; font-size: 3em; color: ${color.white}; `; export const App = styled.div` *, & { box-sizing: border-box; } `;
<ScrollView />
ã³ã³ããŒãã³ãã¯ãå¹
ãšé«ããããã³äžã«è¡šç€ºãããã¹ã¯ããŒã«ããŒã®æ°Žå¹³ããããã£ãããããã£ãšããŠååŸããŸãã
è£å©ã³ã³ããŒãã³ã
圌ãã¯ç§ãã¡ã®çæŽ»ãæ¥œã«ããç§ãã¡ãç©æ¥µçã«åå©çšã«åŸäºã§ããããã«ããŸãã ããã§ã¯ãäžè¬çã«äœ¿çšããããã¹ãŠã®ãã¿ãŒã³ãä¿åããŸãã ç§ã«åœ¹ç«ã€ãã«ããŒã³ã³ããŒãã³ããããã€ã玹ä»ããŸãã
import styled, { css } from "styled-components"; import { borderProps, marginProps, backgroundColorProps, paddingProps, alignmentProps, positioningProps, sizeProps, spacingProps, theme } from "ui"; const { screenSizes } = theme; export const overlay = ` position: fixed; top: 0; left: 0; right: 0; bottom: 0; display: flex; align-items: center; justify-content: center; background: rgba(0,0,0,0.5); `; // You can use this like ${media.phone`width: 100%`} export const media = Object.keys(screenSizes).reduce((accumulator, label) => { const acc = accumulator; acc[label] = (...args) => css` @media (max-width: ${screenSizes[label]}em) { ${css(...args)} } `; return acc; }, {}); // Spacing export const Padder = styled.section` padding: ${props => props.amount ? props.amount : "2em"}; `; export const Spacer = styled.div` ${spacingProps} `; // Alignment export const Center = styled.div` ${borderProps} ${marginProps} ${backgroundColorProps} ${paddingProps} ${alignmentProps} ${positioningProps} ${sizeProps} text-align: center; margin: 0 auto; `; // Positioning export const Relative = styled.div` ${props => borderProps(props)}; position: relative; `; export const Absolute = styled.div` ${props => marginProps(props)}; ${props => alignmentProps(props)}; ${props => borderProps(props)}; position: absolute; ${props => props.right && `right: ${props.padded ? "1em" : "0"}; `} ${props => props.left && `left: ${props.padded ? "1em" : "0"}`}; ${props => props.top && `top: ${props.padded ? "1em" : "0"}`}; ${props => props.bottom && `bottom: ${props.padded ? "1em" : "0"}`}; `; // Patterns export const Collapsable = styled.section` opacity: 1; display: flex; flex-direction: column; ${props => props.animate && ` transition: transform 300ms linear, opacity 300ms ease-in, width 200ms ease-in, max-height 200ms ease-in 200ms; max-height: 9999px; transform: scale(1); transform-origin: 100% 100%; ${props.collapsed && ` transform: scale(0); transition: transform 300ms ease-out, opacity 300ms ease-out, width 300ms ease-out 600ms; `} `} ${props => props.collapsed && ` opacity: 0; max-height: 0; `} `; export const Ellipsis = styled.div` max-width: ${props => props.maxWidth ? props.maxWidth : "100%"}; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; `; export const Circle = styled.span` ${backgroundColorProps} display: inline-block; border-radius: 50%; padding: ${props => props.padding || '10px'}; `; export const Hidden = styled.div` display: none; `;
ããŒã
ããŒãã¯ãã¢ããªã±ãŒã·ã§ã³å
šäœã§åå©çšã§ããçå®ã®å€ã®åäžã®ãœãŒã¹ã§ãã ã«ã©ãŒãã¬ãããäžè¬çãªã¹ã¿ã€ã«ãªã©ãä¿åãããšäŸ¿å©ã§ãã
export const theme = { color: { primary: "#47C51D", secondary: '#53C1DE', white: "#FFF", black: "#222", border: "rgba(0,0,0,0.1)", base: "rgba(0,0,0,0.4)", alert: '#FF4258', success: 'mediumseagreen', info: '#4C98E6', link: '#41bbe1' }, icon: { color: "gray", size: "15px" }, font: { family: ` -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'`, base: '13px', small: '11px', xsmall: '9px', large: '20px', xlarge: '30px', xxlarge: '50px', }, headings: { family: 'Helvetica Neue', }, gutter: '2em', transition: '300ms ease-in-out' }; export default theme;
ã¡ãªãã
- JSã®ãã¹ãŠã®åã¯ãã³ã³ããŒãã³ãã€ã³ã¿ãŒãã§ã€ã¹ãšã®å®å
šãªçžäºäœçšã«ãããŸãã
className
ã䜿çšããŠã³ã³ããŒãã³ããšã¹ã¿ã€ã«ããã€ã³ãããå¿
èŠã¯ãããŸããïŒããã¯åå ãªãã§è¡ãããŸãïŒã- éçºã®å©äŸ¿æ§ãé«ããã¯ã©ã¹åãšã³ã³ããŒãã³ããžã®ãã€ã³ãã£ã³ã°ãæ°ã«ããå¿
èŠã¯ãããŸããã
çæ
- ãŸã å®éã®ãããžã§ã¯ãã§ãã¹ãããå¿
èŠããããŸãã
- Reactçšã«äœæãããŸããã
- ãããžã§ã¯ãã¯éåžžã«è¥ãã§ãã
- ãã¹ãã¯
aria-label
ãŸãã¯className
ã䜿çšããŠå®è¡ããå¿
èŠããããŸãã
ãããã«
䜿çšãããã¯ãããžãŒïŒSASSãBEMãCSSã¢ãžã¥ãŒã«ããŸãã¯ã¹ã¿ã€ã«ä»ãã³ã³ããŒãã³ãïŒã«ããããããéçºè
ã¯ã·ã¹ãã ã®æ°ããå¯åéšåãå£ãããå°å
¥ãããããããšãªããã³ãŒãããŒã¹ãçŽæçã«éçºã§ããŸãã ã
ãã®ã¢ãããŒãã¯é©åãªã¹ã±ãŒãªã³ã°ã«å¿
èŠã§ãããçŽç²ãªCSSãšBEMã䜿çšãããŠããå Žåã§ãå®çŸã§ããŸãã åå®è£
ã«å¿
èŠãªäœæ¥éãšLOCããã¹ãŠã§ãã äžè¬ã«ãã¹ã¿ã€ã«ä»ãã³ã³ããŒãã³ãã¯ãã»ãšãã©ã®Reactãããžã§ã¯ãã«é©ãããœãªã¥ãŒã·ã§ã³ãšåŒã¶ããšãã§ããŸãã ãŸã ç©æ¥µçã«ãã¹ãããå¿
èŠããããŸããããããžã§ã¯ãã¯ææã«èŠããŸãã