Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
CSS Components
Search
Hiroki Tani
June 21, 2014
Design
15
1.9k
CSS Components
2014-06-21 Frontrend in Nagoya w/ HTML5 NAGOYA
Hiroki Tani
June 21, 2014
Tweet
Share
More Decks by Hiroki Tani
See All by Hiroki Tani
Thinking about CSS Architecture
hilokitani
0
150
Other Decks in Design
See All in Design
地理院地図をもっと楽しく!れきちず新機能のご紹介
hjmkth
1
130
デザイナーのAI活用とチームへの浸透戦略
ukaoli
0
120
portfolio.pdf
onof003
0
160
デザイナー向けフライル説明資料
toshiblues
0
130
アプリ360onWeb使い方と裏ワザ?紹介!
ikejun360
0
270
バイアスを凌ぐデザインとコード ―異動直後にどうふるまうか―
kkaru
0
550
sachi_y_portfolio
sachi337
0
530
ブランドパーソナリティ言語化における生成AI活用の実際
h0sa
0
280
【最新】マズロー安達の弟子実績(1期-4期の26人分)
maslow_akkun
0
2.2k
事例で学ぶ!今日から使えるWebサービスUI改善ポイント
ncdc
0
250
[2025.6.30 もがく中堅デザイナー、キャリアの分岐点] なんでもやる系デザイナーのもがきかた
taka_piya
1
3.3k
【PoCで終わらない】運用フェーズまで見据えたAI駆動UIデザイン/フロントエンド開発実践
kitami
1
350
Featured
See All Featured
YesSQL, Process and Tooling at Scale
rocio
173
14k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
36
2.5k
Done Done
chrislema
185
16k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
33
2.4k
The Cult of Friendly URLs
andyhume
79
6.6k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
30
9.7k
How GitHub (no longer) Works
holman
315
140k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
8
920
We Have a Design System, Now What?
morganepeng
53
7.8k
Faster Mobile Websites
deanohume
309
31k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
Transcript
Beyond the CSS Architecture Components CSS
Front-end Engineer Hiroki Tani github.com/hiloki twitter.com/hiloki inkdesign.jp
CSS Mark-up
CSS Mark-up Designer ➡
CSS Mark-up Designer ➡ Engineer ⬅
CSS
Easy .text { color: red; }
Hard too #main .article { ... } #main .article .title
{ ... } #main .breaking .title { ... } #header #logo img { ... } #header li#logoTop { ... } #header li#logoTop:after { .article-header .datetime s ul.member-list li.member a .widget p,.widget ul { ... } #sidebar .widget { ... } #sidebar li a.register{} body.landing #main sectio #slider #slider-control > di
CSS Architecture
http://codepen.io/hiloki/full/dnGeB
None
<div class="speaker"> <div class="image"> <img src="tani.jpg"> </div> <div class="inner"> <p
class=“name”>…</p> <div class="biography"> <p>...</p> </div> </div> </div>
None
.speaker { overflow: hidden; /* Clearfix */ padding: 20px; background-color:
#fff; } .speaker .image { float: left; margin-right: 15px; } .speaker .image > img { border-radius: 60px; } .speaker .inner { overflow: hidden; } …
None
<div class="book"> <div class="cover"> <img src="book.jpg"> </div> <div class="inner"> <p
class="title">...</p> <p class="info"> ... </p> <div class="intro"> <p>...</p> </div> <ul class="shop"> <li>...</li> </ul> </div> </div>
None
.book { overflow: hidden; /* Clearfix */ padding: 20px; background-color:
#9DBCB8; color: #FFF; } .book .cover { float: left; margin-right: 20px; } .book .inner { overflow: hidden; } .book .title { ... } ...
None
<div class="event"> <a href="event.html"> <div class="thumbnail"> <img src="event.jpg"> </div> <div
class="inner"> <p class="event__name">...</p> </div> </a> </div>
None
.event > a { display: block; } .event .thumbnail {
float: left; margin-right: 15px; } .event .inner { overflow: hidden; } …
None
None
None
<div class="media speaker"> <div class="media__image image"> <img src="tani.jpg"> </div> <div
class="media__body inner"> <p class="name">…</p> <div class="biography"> <p>...</p> </div> </div> </div>
None
/* Media */ .media { overflow: hidden; /* Clearfix */
} .media__image { float: left; margin-right: 15px; } .media__body { overflow: hidden; }
.speaker { overflow: hidden; /* Clearfix */ padding: 20px; background-color:
#fff; } .speaker .image { float: left; margin-right: 15px; } .speaker .image > img { border-radius: 60px; } .speaker .inner { overflow: hidden; } … .speaker { overflow: hidden; /* Clearfix */ padding: 20px; background-color: #fff; } .speaker .image { float: left; margin-right: 15px; } .speaker .image > img { border-radius: 60px; } .speaker .inner { overflow: hidden; } …
.speaker { overflow: hidden; /* Clearfix */ padding: 20px; background-color:
#fff; } .speaker .image { float: left; margin-right: 15px; } .speaker .image > img { border-radius: 60px; } .speaker .inner { overflow: hidden; } …
None
.book { overflow: hidden; /* Clearfix */ padding: 20px; background-color:
#9DBCB8; color: #FFF; } .book .cover { float: left; margin-right: 20px; } .book .inner { overflow: hidden; } .book .title { ... } ...
None
.event > a { display: block; } .event .thumbnail {
float: left; margin-right: 15px; } .event .inner { overflow: hidden; } …
None
None
<div class=“media book"> <div class=“media__image book__cover”> <img src="book.jpg"> </div> <div
class=“media__body”> <p class="book__name">...</p> <p class="book__info"> ... </p> <div class="book__intro"> <p>...</p> </div> <ul class="book__shop"> <li>...</li> </ul> </div> </div>
None
.book { padding: 20px; background-color: #9DBCB8; color: #FFF; } .book__cover
{ margin-right: 20px; } .book__title { ... } ...
OOCSS Nicole Sullivan @stubbornella
OOCSS SMACSS BEM MCSS FLOCSS
CSS Components
= encapsulation Components
Not perfect Components
None
<div class="book"> <div class="book__cover"> <p class=“book__name"> … </p> </div> </div>
<div id="pickup"> <div class="book"> <div class="book__cover"> <p class="book__name"> CSS…</p>... </div>
</div> </div> <div class="book"> <div class="book__cover"> <p class=“book__name"> … </p> </div> </div>
None
#pickup .book__name { color: #111; font-size: 2em; } ! .book__name
{ margin-bottom: 10px; line-height: 1.3; font-weight: bold; font-size: 1.2em; }
☢
None
#pickup .book__name { color: #111; font-size: 2em; } ! .book__name
{ margin-bottom: 10px; line-height: 1.3; font-weight: bold; font-size: 1.2em; background-color: #333; padding: 6px; }
None
#pickup .book__name { color: #111; font-size: 2em; background-color: #FFF; padding:
0; } ! .book__name { margin-bottom: 10px; line-height: 1.3; font-weight: bold; font-size: 1.2em; background-color: #333; padding: 6px; }
<style scoped>
None
<div><!-- Scope --> <style scoped> .book__name { background-color: #333; padding:
6px; } </style> <div class=“media book"> <div class=“media__body”> <p class=“book__name”> … </p> </div> </div> </div>
<style scoped> ⛼
<style scoped> ⛼
Components
Sharable Maintainable Easily-controlled
Components Web
Web Components Templates Shadow DOM HTML Imports
Custom Elements
Templates <template id="my-media-template"> <div class="media"> <div class="media__image"> <img> </div> <div
class="media__body"> <content></content> </div> </div> </template>
Custom Elements <google-map></google-map> ! <x-calendar today></x-calendar> ! <button is="like-button"></button> !
<my-media src="tani.jpg" width="120" height="120">
Custom Elements var element = Object.create( HTMLElement.prototype ); document.registerElement( 'my-alert',
{ prototype: element } );
Shadow DOM // ΧελϜཁૉͷΠϯελϯε͕ੜ͞Εͨ࣌ʹ࣮ߦ͢Δ element.createdCallback = function() { var template
= document.querySelector('#my-media- template'); ! // templateͷDocumentFragment͔ΒcontentΛऔಘ͢Δ var content = template.content; ! // Shadow RootʹcontentΛՃ͢ΔʢShadowDOMͷܗʣ var shadowRoot = this.createShadowRoot(); shadowRoot.appendChild( document.importNode(content, true) ); };
Shadow DOM // ΧελϜཁૉͷΠϯελϯε͕ੜ͞Εͨ࣌ʹ࣮ߦ͢Δ element.createdCallback = function() { var template
= document.querySelector('#my-media- template'); ! // templateͷDocumentFragment͔ΒcontentΛऔಘ͢Δ var content = template.content; ! // Shadow RootʹcontentΛՃ͢ΔʢShadowDOMͷܗʣ var shadowRoot = this.createShadowRoot(); shadowRoot.appendChild( document.importNode(content, true) ); }; = encapsulation
HTML Imports <head> <link rel="import" href=“components/my-media.html"> </head>
Web Components Templates Shadow DOM HTML
Imports Custom Elements
http://codepen.io/hiloki/full/obFui
None
<my-media src=“sensui.jpg" width=“120" height=“120" class="speaker"> <p class=“speaker__name"> ઘਫ ᠳޗ </p>
<div class="speaker__bio"> <p>…</p> </div> </my-media>
None
<my-media src="sensui.jpg" width="120" height="120" class="speaker"> <p class=“speaker__name"> ઘਫ ᠳޗ </p>
<div class="speaker__bio"> <p>…</p> </div> </my-media>
None
<my-media src=“book.jpg" width=“100" height=“100" class="book"> <p class=“book__name"> ϑϩϯτΤϯυ… </p> <div
class=“book__info”> <p>…</p> </div> … </my-media>
None
None
<div class="media speaker"> <divclass=“media__image speaker__image”> <img src="tani.jpg" width="120"> </div> <div
class="media__body"> <p class=“speaker__name"> ୩ थ </p> ... </div> </div>
None
<my-media src=“sugimoto.jpg" width=“120" class="speaker"> <p class=“speaker__name"> ਿຊ ٢ষ </p> ...
</my-media>
None
None
<my-media src="sugimoto.jpg" width="120" class="speaker"> <div class="media"> <div class=“media__image"> <img src="tani.jpg"
width="120"> </div> <div class="media__body"> <p class="speaker__name">ਿຊ ٢ষ</p> ... </div> </div> </my-media>
None
<div class="media speaker"> <div class="media__image speaker__image"> <img src="tani.jpg" width="120"> </div>
<div class="media__body"> <p class="speaker__name">୩ थ </p> ... </div> </div>
/* <head> <style>…</style> </head> */ .media { display: block; overflow:
hidden; /* Clearfix */ color: indianred; } ❓
/* <head> <style>…</style> </head> */ .media { display: block; overflow:
hidden; /* Clearfix */ color: indianred; }
/* <head> <style>…</style> </head> */ .media { display: block; overflow:
hidden; /* Clearfix */ color: indianred; }
/* <template> <style>…</style> </template> */ .media { display: block; overflow:
hidden; /* Clearfix */ color: skyblue; } ❓
/* <template> <style>…</style> </template> */ .media { display: block; overflow:
hidden; /* Clearfix */ color: skyblue; }
/* <template> <style>…</style> </template> */ .media { display: block; overflow:
hidden; /* Clearfix */ color: skyblue; }
::shadow
/* <head> <style>…</style> </head> */ .speaker::shadow .media { display: block;
overflow: hidden; /* Clearfix */ background-image: url(orion.jpg); background-size: cover; } ❓
/* <head> <style>…</style> </head> */ .speaker::shadow .media { display: block;
overflow: hidden; /* Clearfix */ background-image: url(orion.jpg); background-size: cover; }
Shadow DOM = encapsulation Custom Elements <my-media></my-media>
Shadow DOM = encapsulation Custom Elements
Shadow DOM = encapsulation Custom Elements <my-media> <style> .media {
display: block; overflow: hidden; /* Clearfix */ } .media__image { float: left; margin-right: 10px; } .media__body { overflow: hidden; } </style> <div class="media"> <div class=“media__image"></div> <div class="media__body"></div> </div> </my-media>
Shadow DOM = encapsulation Custom Elements <my-media> ! ! !
! ! ! ! ! ! ! ! ! ! ! ! ! </my-media>
Shadow DOM = encapsulation Custom Elements <my-media> ! ! !
! ! ! ! ! ! ! ! ! ! ! ! ! </my-media> ! <style> .media { display: table; } .media__image { display: table-cell; vertical-align: top; padding-right: 10px; } </style> <div class="media"> <div class=“media__image"></div> <div class="media__body"></div> </div>
Shadow DOM = encapsulation Custom Elements <my-media> ! ! !
! ! ! ! ! ! ! ! ! ! ! ! ! </my-media>
Shadow DOM = encapsulation Custom Elements <my-media> ! ! !
! ! ! ! ! ! ! ! ! ! ! ! ! </my-media> ! <style> .media { display: flex; align-items: flex-start; } .media__image { margin-right: 10px; } .media__body { flex: 1; } </style> <div class="media"> <div class=“media__image"></div> <div class="media__body"></div> </div> !
Shadow DOM = encapsulation Custom Elements <my-media></my-media>
HTML5 Rocks http://www.html5rocks.com/
Polymer http://www.polymer-project.org/
X-Tag http://www.x-tags.org/
In future
Polymer designer https://github.com/Polymer/designer
Designer Builder Component Component
Designer Builder Component Component
Component Designer. Be a
Thank you. github.com/hiloki twitter.com/hiloki inkdesign.jp
https://www.flickr.com/photos/premshree/3444104640/ https://www.flickr.com/photos/ltdemartinet/8331549172/ https://www.flickr.com/photos/horiavarlan/4839454263/ https://www.flickr.com/photos/drewmaughan/8209503226/ Photos: