Share
Embed
10 Commandments for Efficient CSS Architecture [CSSConf.Asia '14]
CSS is a very funny language. That is something we all have realised at some point or the other while working with it. If not used correctly, a language used to make things look good can itself start looking bad and we can end up with CSS that is hard to manage and extend. This talk is about 10 things which I have learnt from experience can make one’s CSS manageable and easy to extend, specially in large scale applications.
Kushagra Gour
January 18, 2015
Transcript
44 slides
-
10* COMMANDMENTS FOR EFFICIENT CSS ARCHITECTURE Yes, CSS can have
architecture too! Kushagra Gour @chinchang457 * Conditions apply. -
/me My name is . Better know as on the
web. Kushagra Gour chinchang I am from Delhi, India -
/me more I am a Front-end developer at a wonderful
startup called Wingify. Open-source stuff like and Hint.css piCSSel-art. -
Whats this talk about? Some CSS goodies learnt from experience.
Would help in better CSS architecture. Easy to understand and extend in future. No more Careless Style Sprinkling. First time speaking at a conference and that too at such a big one. Not really good at speaking & making presentations. // TODO: Add a game if slides don't complete. Good at making games. Added a game we can all play together and have fun! Seriously! -
Commandment #1 Keep File Sizes Small "Thy height shalt remain
greater than thy file sizes at all times" -
Keep File Sizes Small Why? It helps keeping things modular.
Important for faster search in future because you know where things are when something needs to be changed. What? Keep dividing and refactoring files as and when they get too big. -
4th day of christmas 1. base.css 2. helpers.css 3. components.css
4. theme.css 5. mixins.scss (SASS) -
8th day of christmas 1. base.css 2. helpers.css 3. components/
buttons.css dropdowns.css tooltips.css 4. theme.css -
Use Variables Your layout: HEADER SIDEBAR CONTENT . h e
a d e r { w i d t h : 1 0 0 % ; h e i g h t : 5 0 p x ; / / M a g i c n u m b e r } . s i d e b a r { w i d t h : 1 0 0 p x ; / / M a g i c n u m b e r h e i g h t : 1 0 0 % ; t o p : 5 0 p x ; / / M a g i c n u m b e r } . c o n t e n t { t o p : 5 0 p x ; / / M a g i c n u m b e r b o t t o m : 0 ; l e f t : 1 0 0 p x ; / / M a g i c n u m b e r r i g h t : 0 ; } Too many magic numbers! -
Use Variables Better approach $ h e a d e
r - h e i g h t : 5 0 p x ; $ s i d e b a r - w i d t h : 1 0 0 p x ; . h e a d e r { w i d t h : 1 0 0 % ; h e i g h t : $ h e a d e r - h e i g h t ; } . s i d e b a r { w i d t h : $ s i d e b a r - w i d t h ; h e i g h t : 1 0 0 % ; } . c o n t e n t { t o p : $ h e a d e r - h e i g h t ; b o t t o m : 0 ; l e f t : $ s i d e b a r - w i d t h ; r i g h t : 0 ; } -
Use Variables Better approach Less error prone Easy extensibility $
h e a d e r - h e i g h t : 5 0 p x ; $ s i d e b a r - w i d t h : 1 0 0 p x ; . h e a d e r { w i d t h : 1 0 0 % ; h e i g h t : $ h e a d e r - h e i g h t ; } . s i d e b a r { w i d t h : $ s i d e b a r - w i d t h ; h e i g h t : 1 0 0 % ; } . c o n t e n t { t o p : $ h e a d e r - h e i g h t ; b o t t o m : 0 ; l e f t : $ s i d e b a r - w i d t h ; r i g h t : 0 ; } -
Component Abstractions Scenario: HUD elements on a game screen .
h u d - s t a t s { p o s i t i o n : f i x e d ; o p a c i t y : 0 . 7 ; f i l t e r : s e p i a ( 9 0 % ) ; b o t t o m : 2 0 p x ; l e f t : 2 0 p x ; } . h u d - m a p { p o s i t i o n : f i x e d ; o p a c i t y : 0 . 7 ; f i l t e r : s e p i a ( 9 0 % ) ; t o p : 2 0 p x ; r i g h t : 2 0 p x ; } -
Component Abstractions Scenario: HUD elements on a game screen .
h u d - s t a t s { p o s i t i o n : f i x e d ; o p a c i t y : 0 . 7 ; f i l t e r : s e p i a ( 9 0 % ) ; b o t t o m : 2 0 p x ; l e f t : 2 0 p x ; } . h u d - m a p { p o s i t i o n : f i x e d ; o p a c i t y : 0 . 7 ; f i l t e r : s e p i a ( 9 0 % ) ; t o p : 2 0 p x ; r i g h t : 2 0 p x ; } Too much repeatition. -
Component Abstractions HUD elements on a game screen (Better) .
h u d - e l e m e n t { p o s i t i o n : f i x e d ; o p a c i t y : 0 . 7 ; f i l t e r : s e p i a ( 9 0 % ) ; } . h u d - s t a t s { b o t t o m : 2 0 p x ; l e f t : 2 0 p x ; } . h u d - m a p { t o p : 2 0 p x ; r i g h t : 2 0 p x ; } < d i v c l a s s = " h u d - e l e m e n t h u d - s t a t s " > 9 9 9 9 < / d i v > No repeation. Much cleaner. -
Component Abstractions HUD elements on a game screen (Better)(SASS) %
h u d - e l e m e n t { p o s i t i o n : f i x e d ; o p a c i t y : 0 . 7 ; f i l t e r : s e p i a ( 9 0 % ) ; } . h u d - s t a t s { @ e x t e n d % h u d - e l e m e n t ; b o t t o m : 2 0 p x ; l e f t : 2 0 p x ; } . h u d - m a p { @ e x t e n d % h u d - e l e m e n t ; t o p : 2 0 p x ; r i g h t : 2 0 p x ; } < d i v c l a s s = " h u d - s t a t s " > 9 9 9 9 < / d i v > -
Commandment #4 Keep Selector Strengths Low Thou shalt spread peace
and stop thy selectors from fighting. -
Keep Selector Strengths Low Selectors have strengths...and they do fight!
Example: d i v . t a b s { w i d t h : 1 0 0 % ; } < d i v c l a s s = " t a b s " > < / d i v > . t a b s - h a l f { w i d t h : 5 0 % ; } < d i v c l a s s = " t a b s t a b s - h a l f " > < / d i v > WON'T WORK! s t r e n g t h ( d i v . t a b s ) > s t r e n g t h ( . t a b s - h a l f ) -
Keep Selector Strengths Low How things get messier... Either prefix
your class name with tag. Use the all 'awesome and criticized' Plus, tabs can only be made up of tags. DIV ! i m p o r t a n t DIV -
Keep Selector Strengths Low No d i v . t
a b s Simply have . t a b s -
Commandment #5 Naming Convention Thou shalt treat your classes as
thy own children. Name them with equal love. -
Naming Convention Most important thing in CSS. Much more important
than any other languauge. Some things are bad in CSS (ahem...!important) and can be eliminated through better naming. -
Naming Convention : Block - Element - Modifier BEM -
Component - Sub-part of component - Variation of component Block Element Modifier Supports Component abstraction -
Naming Convention : Naming BEM - . c o m
p o n e n t - . c o m p o n e n t _ _ s u b - p a r t - . c o m p o n e n t - - v a r i a t i o n Block Element Modifier -
Naming Convention - Example - Without BEM BEM 20 .
s l i d e r { p o s i t i o n : r e l a t i v e ; } . s l i d e r . s l i d e r - t r a c k { b a c k g r o u n d : w h i t e ; } . s l i d e r . k n o b { p o s i t i o n : a b s o l u t e ; } / / V a r i a t i o n . s l i d e r . s l i d e r - w i t h - i n p u t . s l i d e r - i n p u t { d i s p l a y : b l o c k ; } -
Naming Convention - Example - With BEM BEM . s
l i d e r { p o s i t i o n : r e l a t i v e ; } . s l i d e r _ _ t r a c k { b a c k g r o u n d : w h i t e ; } . s l i d e r _ _ k n o b { p o s i t i o n : a b s o l u t e ; } / / V a r i a t i o n . s l i d e r - - w i t h - i n p u t . s l i d e r _ _ i n p u t { d i s p l a y : b l o c k ; } Selectors - Less specific. More uniform. -
Commandment #6 z-index Management Thou shalt not mix up thy
ego and z-indexes -
z-index Management Separate them out into your config as variables
$ z - i n d e x - o v e r l a y : 1 ; $ z - i n d e x - s l i d e o u t - b a c k d r o p : 1 ; $ z - i n d e x - s l i d e o u t : 1 ; $ z - i n d e x - s i d e b a r : 2 ; / / a b o v e h e l p p a n e l f o r t o o l t i p s $ z - i n d e x - n a v i g a t i o n : 4 ; / / t o p o f s i d e b a r $ z - i n d e x - h e a d e r : 4 ; $ z - i n d e x - m o d a l - u n d e r l a y : 4 ; / / B e l o w m o d a l - b o x & t o p o f $ z - i n d e x - m o d a l - b o x : 5 ; / / o n t o p o f e v e r y t h i n g -
z-index Management Changing existing z-indexes become really easy because you
know what might break. Setting z-index for new UI elements is very easy because you can actually position it in a similar hierarchy. -
z-index Management No more z - i n d e
x : 9 9 9 9 9 ; -
@extend - Avoid Selector Hell Simple example: SASS . e
r r o r { c o l o r : r e d ; b a c k g r o u n d : # f f 8 8 8 8 ; } . s i d e b a r { . e r r o r { p a d d i n g : 1 0 p x ; } } . e r r o r - n o t i f i c a t i o n { @ e x t e n d . e r r o r ; / / G O N N A B E B A D ! ! ! } -
@extend - Avoid Selector Hell Result SASS: CSS: . e
r r o r { c o l o r : r e d ; b a c k g r o u n d : # f f 8 8 8 8 ; } . s i d e b a r { . e r r o r { p a d d i n g : 1 0 p x ; } } . e r r o r - n o t i f i c a t i o n { @ e x t e n d . e r r o r ; } . e r r o r , . e r r o r - n o t i f i c a t i o n { c o l o r : r e d ; b a c k g r o u n d : # f f 8 8 8 8 ; } . s i d e b a r . e r r o r , . s i d e b a r . e r r o r - n o t i f i c a t i o n { p a d d i n g : 1 0 p x ; } Unnecessary CSS generated -
@extend - Avoid Selector Hell Solution: Use placeholders SASS: CSS:
% e r r o r { c o l o r : r e d ; b a c k g r o u n d : # f f 8 8 8 8 ; } . e r r o r { @ e x t e n d % e r r o r ; } . s i d e b a r { . e r r o r { p a d d i n g : 1 0 p x ; } } . e r r o r - n o t i f i c a t i o n { @ e x t e n d % e r r o r ; } . e r r o r , . e r r o r - n o t i f i c a t i o n { c o l o r : r e d ; b a c k g r o u n d : # f f 8 8 8 8 ; } . s i d e b a r . e r r o r { p a d d i n g : 1 0 p x ; }