Slide 1

Slide 1 text

How to Deal with Technical Debt of CSS Takuya Matsumoto @upinetree Rails Developer Meetup 2019 Day 1 2019.03.22

Slide 2

Slide 2 text

Takuya Matsumoto @upinetree Everyleaf corp. גࣜձࣾ ສ༿ Programmer Hometown: Nagaoka, Niigata, Japan Love: Sake, Guitar, Game

Slide 3

Slide 3 text

#ݱ৔Rails ͕Μ͹Γ·ͨ͠

Slide 4

Slide 4 text

TODAY'S Theme Technical Debt of CSS

Slide 5

Slide 5 text

Consider the problem in a point of view of a programmer based on my experiences

Slide 6

Slide 6 text

Why does CSS technical debt happen

Slide 7

Slide 7 text

Have you seen problems like below? • Changing CSS occurs unintended effects • Styles broken when some HTML structures are changed • Don't know how CSS affects so no one want to touch them • No styles applied for some unknown reasons • Leave to stand unused CSS because removing them is terrible

Slide 8

Slide 8 text

Accumulated debts cause development bottlenecks • Hard to touch CSS by physically and psychologically reasons • Spend much more time for a small change of styles • A teammate great on CSS has heavy workloads and becomes a SPOF • Even shrink entire business

Slide 9

Slide 9 text

This structure seems same with the (Ruby) programming from the point of view of a technical debt

Slide 10

Slide 10 text

Unlike some programming language, I think there are many teams lacking discussion about a technical debt of CSS

Slide 11

Slide 11 text

Why?

Slide 12

Slide 12 text

Examine a background of CSS

Slide 13

Slide 13 text

CSS works simple • It has some rules like a Specificity but basically styles applied just as written • Clear and straightforward in the earliest stage • Looks superficially fine regardless of the quality • Tend to incur an unpayable debt at high interest without thinking

Slide 14

Slide 14 text

Any language has simplicity at first • Problems underlying CSS are: • Difficulty in structuration • Difficulty in recognizing a fact that the code has a debt • Debt will grow below water and suddenly found without increasing concerns in CSS in a team

Slide 15

Slide 15 text

Development team have to take concerns in too many things DB OS Rails Ruby Business Logic Network JavaScript CSS Device Markup Interaction UI UX Design Illustration Concept * Circle sizes have no meaning

Slide 16

Slide 16 text

DB OS Rails Ruby Business Logic Network JavaScript CSS Device Markup Interaction UI UX Design Illustration Concept teammate A A certain teammate have concerns in

Slide 17

Slide 17 text

DB OS Rails Ruby Business Logic Network JavaScript CSS Device Markup Interaction UI UX Design Illustration Concept teammate A teammate B A certain teammate have concerns in

Slide 18

Slide 18 text

DB OS Rails Ruby Business Logic Network JavaScript CSS Device Markup Interaction UI UX Design Illustration Concept teammate A teammate B teammate C A certain teammate have concerns in

Slide 19

Slide 19 text

DB OS Rails Ruby Business Logic Network JavaScript CSS Device Markup Interaction UI UX Design Illustration Concept teammate A teammate B teammate C teammate D A certain teammate have concerns in

Slide 20

Slide 20 text

DB OS Rails Ruby Business Logic Network JavaScript CSS Device Markup Interaction UI UX Design Illustration Concept teammate A teammate B teammate C teammate D A certain teammate have concerns in Programmers in this team... - want to deliver values to users - think can not touch CSS properly - think designers will make CSS good

Slide 21

Slide 21 text

DB OS Rails Ruby Business Logic Network JavaScript CSS Device Markup Interaction UI UX Design Illustration Concept teammate A teammate B teammate C teammate D A certain teammate have concerns in Designers in this team... - think CSS is a one of a expression methods - are difficult to be motivated to design a code

Slide 22

Slide 22 text

CSS The valley outside of concerns

Slide 23

Slide 23 text

"Valley of concerns" ؔ৺ͷ୩ • Valleys are easily eroded between concerns • Tend to think "Someone will do it better than me", if the valley is recognized • There is probably a mass psychology such as "Bystander effect" https://flic.kr/p/f7yxnc

Slide 24

Slide 24 text

How to over the valley of concerns

Slide 25

Slide 25 text

Bridge the valley • Introduce some structures (= bridge) that avoid creating technical debt unconsciously, even if team has intimate knowledge • Note that its effects are limited (because it is just a bridge)

Slide 26

Slide 26 text

3 kind of bridges in this session • CSS Methodologies • Constraints • Choi-tashi class

Slide 27

Slide 27 text

CSS Methodologies

Slide 28

Slide 28 text

CSS Methodologies • Some best practices proposed by forerunners • OOCSS, BEM, SUIT CSS, SMACSS, MCSS, RSCSS, ECSS, ITCSS, FLOCSS, FLOU, ... • Outsource documents and background philosophies • Easy to reach to knowledges and many introduction examples

Slide 29

Slide 29 text

Cons. of CSS Methodologies • Sometimes it is unmatchable for your product • If rules are complicated it is hard to understand and allow other interpretations • Can't remember, can't permeate • Tend to just follow methodologies and lose a original purpose

Slide 30

Slide 30 text

How to decide introducing a CSS methodology • It might be a best when minds and solutions of a methodology is matched to the project and satisfy a team • Otherwise, there is a way that introducing a customized one or only some essences • "Constraints" and "Choi-tashi" are recommended essences in my experience, showing the next

Slide 31

Slide 31 text

Constraints

Slide 32

Slide 32 text

Reasons for Constraints • CSS specifications are simple. Thus CSS codes could be simple or also could be complicated according to how to write it • Create failure-robast structures by introducing constraints • Explain 3 constraints in this session

Slide 33

Slide 33 text

Constraint 1: Class naming convention • Class naming is very important because CSS is explicitly applied by specified selectors • Many competitions due to no scopes • Should be unique and understandable • Methodologies: BEM, SUIT CSS, ECSS

Slide 34

Slide 34 text

BEM https://en.bem.info/ • Component based design approach. It composes a class name by 3 parts: Block, Element, Modifier • BEM itself do not restrict naming convention and "MindBEMding" is often used as a defacto standard .search-form__button--disabled Block Element Modifier

Slide 35

Slide 35 text

Naming using BEM • Using BEM can emulate scopes • Class name should be unique, understandable and less collisions, same with whoever wrote • Accept trade-off: verbose class name, weird symbols such as __ and --

Slide 36

Slide 36 text

Constraint 2: Keep specificity same • Unintended competitions occurred when there are needless differences of specificities • Specified styles are not applied for some unknown reasons • !important will be appeared • Differences of specificities should be designed by intention, but is hard for a team has "Valley of concenrs"

Slide 37

Slide 37 text

Specificity wars .links { font-size: 1.2rem; .pickup { color: #933; } } * Written in Sass style

Slide 38

Slide 38 text

Specificity wars .links { font-size: 1.2rem; .pickup { color: #933; } }
Could be used for the menu too

Slide 39

Slide 39 text

Specificity wars .links { font-size: 1.2rem; .pickup { color: #933; } } #menu { .links { font-size: 1rem; color: #333; } }
The menu should have different looks (high specificity)

Slide 40

Slide 40 text

Specificity wars .links { font-size: 1.2rem; .pickup { color: #933 !important; } } #menu { .links { font-size: 1rem; color: #333; } }
Oh, the color style does not appear. !important must be useful

Slide 41

Slide 41 text

Constraints for preventing unintended specificity changes • No descendant selectors (prevent increase) • No ID selectors (prevent increase) • No type selectors (prevent decrease) • Of course, expression ability of CSS is restricted for constraints

Slide 42

Slide 42 text

example: No descendant selectors Could define exceptions for allowable conditions because it is a strong constraint /* Bad */ #menu { .links { font-size: 1rem; color: #333; .sub-links { font-size: 0.8rem; } } } /* Good */ .menu-links { color: #333; } .menu-links-main { font-size: 1rem; } .menu-links-sub { font-size: 0.8rem; }

Slide 43

Slide 43 text

Constraint 3: Separate layout from style • Specifying layouts and looks in a same class sometimes causes overwrite and duplication because it is hard to reuse • Layout-separated classes are reusable and flexible

Slide 44

Slide 44 text

example: Separation of layout and looks Child selectors increase specificity, but it is useful to limit a range (refs. RSCSS) /* Layout (prefix: -l) */ .l-comments { > .comment { margin-top: 8px; } > .comment + .comment { margin-left: 4px; } } /* Looks */ .comment { display: block; border: 1px solid #aaa; }

Slide 45

Slide 45 text

Cons. of separation of layout and looks • Trade-off of a cohesion for a component • Over separated classes increase dependency from HTML and it is difficult to use • Introducing a layout layer and not requiring separation could be a good way • refs: SMACSS, MCSS, ITCSS, FLOCSS, FLOU

Slide 46

Slide 46 text

Choi-tashi class

Slide 47

Slide 47 text

Choi-tashi class • "Choi-tashi" == "Small addition" in Japanese • Generally it is called "Utility" • Some CSS frameworks have this kind of classes
 (Bootstrap 4, UIKit, Tailwind CSS, Foundation 6, ...)
Hello
World

Slide 48

Slide 48 text

Pros. of choi-tashi • Help separation of layout from style • Just focus to core styles of a component • Could handle styles equally without any CSS knowledge • Decrease frequency of designer reviews whether CSS satisfies design basis

Slide 49

Slide 49 text

What should be choi-tashi Classes for design basis • Spacing (margin, padding) • Typography (font-size, line- height) • Color variations Classes for layout separation • Flexbox • Float • Display

Slide 50

Slide 50 text

Avoid over choi-tashi • Increasing dependency from HTML to CSS causes tight coupling and larger effects from changes • Creating class is a recommended way in such cases • Defining max choi-tashi count is effective • a joke: https://github.com/marmelab/universal.css

Slide 51

Slide 51 text

Keep simple choi-tashi class • Specify stable styles because it's used in broad range • It is desired that effects of changes are always intended • Avoid overwrite them using kind of descendant selectors. Effects become hard to predict

Slide 52

Slide 52 text

Limitation of the bridge

Slide 53

Slide 53 text

Big bridge • Complicated rules • Diversified choi-tashi classes • Checking appropriate usage of a bridge puts a strain • Confusion by unintended usages • Maintenance costs of a bridge is increasing

Slide 54

Slide 54 text

Valley of concerns is still exists • Not resolved basically yet • A bridge is effective but it essentially means that high-interest debt is just transferred to low-interest debt • Valley itself should be addressed to keep a bridge size as necessary and sufficient

Slide 55

Slide 55 text

Filling a valley • Expand concerns of a team and build a culture for dealing CSS with a whole team • Embracing learning costs is needed. Then, a team could be design and review without any individualization • Action of a team

Slide 56

Slide 56 text

Feature comparison 4PMWBCMFQSPCMFNT 'FBTJCJMJUZBOE TVTUBJOBCJMJUZ #VJMEB CSJEHF -JNJUFE &BTZ
 4UBSUTNBMM 'JMMBWBMMFZ 'VOEBNFOUBMMZ )BSE 6ONFBTVSBCMF

Slide 57

Slide 57 text

• Filling a valley is ideal but hard for a team that has bigger valley • Start from a bridge, then fill a valley gradually in parallel Solvable problems Feasibility and sustainability Build a bridge Limited Easy
 Start small Fill a valley Fundamentally Hard Unmeasurable Feature comparison

Slide 58

Slide 58 text

In what order should deal with them

Slide 59

Slide 59 text

A development team • Low productivity due to debts of CSS • Depends on a teammate who is great on CSS

Slide 60

Slide 60 text

Please review it! A development team • A lot of works, become a bottleneck Adjustment is required! Code them!

Slide 61

Slide 61 text

Merge it once before a deadline A development team • If they can not handle tasks, then a debt grows, and more works are coming...it is a negative cycle Well, here goes nothing Wait for a while…

Slide 62

Slide 62 text

How to address such a team • Hire a front-end engineer? • Could be resolved temporary • In the long term, the bottleneck will move to the new member and the negative cycle will continue

Slide 63

Slide 63 text

• Stop the negative cycle first, and stop incurring debts without a plan • Next, create a structure repayable debts How to address such a team

Slide 64

Slide 64 text

A first small bridge • Introduce choi-tashi class, named "Utility" • Easily start using and affect a debt • Slow down growing debts • Reduce works of a teammate great on CSS • Useful for refactoring

Slide 65

Slide 65 text

Have everyone use the bridge • A bridge no one knows is meaningless • Create a style guide and make it known • Use a generator for the style guide • Astrum, Hologram, Fractal, SC5, and so on

Slide 66

Slide 66 text

Astrum http://astrum.nodividestudio.com/

Slide 67

Slide 67 text

What contents should be listed • Defined Utilities, examples, notices • How to update the style guide itself

Slide 68

Slide 68 text

Create rules • Policies for new classes • Create an agreement for what kind of methodologies and constraints should be adopted • It should be shown in the style guide and be easy to access

Slide 69

Slide 69 text

In a new page, it is safely implemented with "Utilities could be used without hesitation" and "Rules preventing failures"

Slide 70

Slide 70 text

Negative cycle now stopped • CSS in existing pages are still fragile • It blocks instilling new rules • Refactor existing codes to good structures

Slide 71

Slide 71 text

Before start refactoring • Classes have debts are used widely and even be overwritten • Difficult to check unintended effects due to refactoring

Slide 72

Slide 72 text

Visual regression testing • Automating the testing of how software looks • Detect differences of screenshots and test there are no unintended change • Some tools are established • BackstopJS, REG-SUIT

Slide 73

Slide 73 text

BackstopJS My post for explaining how to use BackstopJS on Rails (ja) http://upinetree.hatenablog.com/entry/2018/05/13/231951

Slide 74

Slide 74 text

Start of steady refactoring work • High priority on a high effectiveness or big issue • Reduce repeated but different classes have same styles and same purpose • Separate over reused classes for different purposes • Tweaking code is tempting but it makes refactoring to feel far

Slide 75

Slide 75 text

Discovery in the refactoring • Common structures should be found • ex. Layout like a grid system • Classify them and make it reusable

Slide 76

Slide 76 text

Do not make code over DRYed • Problem of duplication is small rather than code reuse if class is used for different purpose • Mix-in is the same. Abstraction should be duly considered

Slide 77

Slide 77 text

Taking a break is always important ☕ • Refactoring CSS is nothing special, but not a mindless work • It requires a careful work while figuring out the whole structures of the application • Move things forward steadily because a negative cycle is already stopped now

Slide 78

Slide 78 text

Steady and crude way, but continue • Code is gradually getting clear • Yield insight about system-wide knowledge • Better to collaborate with all members of a team • It is opportunities of expanding concerns and filling a valley

Slide 79

Slide 79 text

Summary

Slide 80

Slide 80 text

Summary • The root of technical debts of CSS is a "Valley of concerns" • Bridge to a valley with "CSS Methodologies", "Constraints", "Choi-tashi classes" • Bridge has a limitation so filling a valley is also needed • A road of repaying debs is too long but starting small is easy!

Slide 81

Slide 81 text

Appendix

Slide 82

Slide 82 text

example of allowable descendant selectors: Block closed definition /* Good */ .carousel { font-size: 1rem; .home & { font-size: 2rem; } } Specificity changes of .carousel is closed in the block {} so the effects is easily forecastable /* Bad */ .carousel { font-size: 1rem; } .home { .carousel { font-size: 2rem; } }