# Good CSS Is Easy To Change [gregorymcintyre.com](https://gregorymcintyre.com) 2018 ==== ## Ruby, JavaScript, etc. What is "quality"? What is "good"? ==== ## Good code = easy to change ![Corey Haines](corey-haines.jpg) Corey Haines ==== ## Easy to change * Verifiable * Expresses intent * No repetition * Concise ==== ## Verifiable You can quickly tell that a change you make works ==== ## Expresses intent You can tell what the code is trying to do ==== ## No repetition You only edit one bit of code per logical change you wish to make ==== ## Concise You don't have to read a 100 page manual to get started ==== ## What if we applied these to....... CSS? ==== ```css ul.data_rows { padding: 0px 0px 0px 20px; } ul.data_rows li{ background: rgb(214, 245, 255) url(/images/friends_icon.png) 10px center no-repeat; overflow: hidden; padding: 10px 10px 10px 50px; margin: 10px 0 10px 10px; border: 2px solid rgb(214, 245, 255); -moz-border-radius: 2px; -webkit-border-radius: 2px; border-radius: 2px; } ul.data_rows.w635 { width: 660px !important; } ``` From a real project ==== ```ruby def style_data_rows(el) el.padding = [0, 0, 0, 20] el.each_item do |item| item.background = [rgb(214, 245, 255), '/images/friends_icon.png', 10, :center, :no_repeat] item.overflow = :hidden item.padding = [10, 10, 10, 50] item.margin = [10, 0, 10, 10] item.border = [2, :solid, rgb(214, 245, 255)] item.border_radius = 2 end el.width = 660 if el.has_class?('w636') end ``` ==== ## Most projects I've seen <img src="quality-chart.png" alt="Quality: Code 80% CSS 20%"> ==== # Why? ==== ## "CSS is a configuration file" Can it break * Purchases? ✔ * Logging in? ✔ * Most features you can think of? ✔ Somebody implemented <a href="https://keithclark.co.uk/labs/css-fps/">Doom in CSS</a>. ==== ## "Internet Explorer cut me" ![Life is pain](life-is-pain.gif) ==== ## "CSS is graphic design" ![Not my job!](not-my-job.jpg) ==== ## Low morale <img src="arial-frustrated.png" alt="Arial is frustrated"> ==== ## How can we make CSS better? ==== ## Step 1 How can we make CSS ~~better~~ easier to change? ==== ## Review * Verifiable * Expresses intent * No repetition * Concise ==== ## Verifiable * Good QA * Automated tools ==== ## Expresses intent ```css .page { overflow: hidden; } .page article { float: left; } .page aside { float: right; } ``` ==== ## Express intent with comments ```css .page { overflow: hidden; /* clearfix */ } .page article { float: left; /* big column */ } .page aside { float: right; /* small column */ } ``` ==== ## Express intent with OOCSS ```html <style> .column-container { overflow: hidden; } .big-column { float: left; } .small-column { float: right; } </style> <div class="column-container page"> <article class="big-column"> </article> <aside class="small-column"> </aside> </div> ``` ==== ## Express intent with SASS mixins ```scss @mixin column-container { @include clearfix; } @mixin big-column { float: left; } @mixin small-column { float: right; } .page { @include column-container; article { @include big-column; } aside { @include small-column; } } ``` ==== ## No repetition ```css .data_rows li { background-color: rgb(214, 245, 255); border: 2px solid rgb(214, 245, 255); -moz-border-radius: 2px; -webkit-border-radius: 2px; border-radius: 2px; } ``` ==== ## No repetition with variables ```scss $pale-bg: rgb(214, 245, 255); $border-width: 2px; .data_rows li { background-color: $pale-bg; border: $border-width solid $pale-bg; } ``` ==== ## No repetition with calculations ```scss // css .container { width: 698px; border: 1px; } // sass $container-border: 1px; .container { width: 700px - 2 * $container-border; border: $container-border; } ``` ==== ## No repetition with nesting ```scss .my-long-selector { /* ... */ } .my-long-selector input { /* ... */ } .my-long-selector { /* ... */ input { /* ... */ } } ``` ==== ## Concise Can we reduce the total amount of CSS? ==== ## Concise by removing unused CSS Well, yeah ==== ## Concise by preprocessing Bootstrap ```scss // include it @import bootstrap; // override it input { background-color: $sexy-smoke; } ``` Browser <pre class="hljs"> input { background-color: #eee; } /* override */ <s>input { background-color: #fff; }</s> /* bootstrap */ </pre> ==== ## Concise by configuring Bootstrap ```scss $input-bg: $sexy-smoke; // configure it @import bootstrap; // include it input { } // simpler ``` Browser <pre class="hljs"> input { background-color: #eee; } /* bootstrap */ </pre> ==== ## Concise by reusing CSS "NoCSS" ==== ## NoCSS, chapter 1 No re-use <img class="borderless" src="worst.png" alt=""> ==== ## Introduce baseline CSS ```css /* Normalize, Bootstrap, Foundation, or Material UI */ /* Or your own handcrafted job */ /* Built in HTML tags */ ul { } blockquote { } article header { } /* Very re-usable, very focused classes (OOCSS) */ .text-center { } ``` ==== ## NoCSS, chapter 2 New baseline <img class="borderless" src="typical.png" alt=""> ==== ## Introduce reusable components ```css /* .client-calendar {} */ .calendar { } /* .product-list {} */ .gallery { } /* .sales-chart {} */ .line-chart { } ``` ==== ## NoCSS, chapter 3 <img class="borderless" src="ideal.png" alt=""> ==== ## NoCSS updates * Add HTML (with the right classes) * Add frontend/backend code so it functions * It already looks good! * ~~Add and update CSS~~ (e.g. when Bootstrap actually works well) ==== # Summary ==== ## Just one way to measure "quality" * Verifiable * Expresses intent * No repetition * Concise ==== <img src="scorecard.png" alt=""> ==== ## Conclusions * Please assess your CSS's maintainability * Use tools or techniques * Some effort pays off ==== ## Conclusions * But... don't be a perfectionist ;) ==== [gregorymcintyre.com/slides/good-css-is-easy-to-change/](https://gregorymcintyre.com/slides/good-css-is-easy-to-change/#/)