~wuz/wuz.sh

ref: 659dedfc35bdd3807b6d8d59ab47049257fb0eb3 wuz.sh/_site/styles/README/index.html -rw-r--r-- 7.5 KiB
659dedfc — Conlin Durbin Rename posts to writing 1 year, 3 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
<p>I've been thinking about how we manage our styles currently and how we might manage them going forward, especially with the Design System and the number of engineers we have right now. I've read a good amount about how other companies handle CSS/SCSS and worked to create something that I feel fits our organization and gives us the ability to create maintainable CSS structures. We aren't here yet, but I think as we move forward with the design system, we have an opportunity to rethink how we handle some of our CSS. Without further ado, I'd like to present SCCSS (success!), a framework for managing CSS at scale at Lessonly.</p>
<h3>A Framework for SCCSS (success)</h3>
<p>With a good framework in place, our CSS can be easy to work with and simple to modify. The framework used here is based on <a href="https://smoothie-css.com">Smoothie CSS</a> and is defined as such:</p>
<p>All styles at Lessonly belong to one of three categories: Token, Framework, and Component.</p>
<h4>Tokens</h4>
<p>Tokens are the base units of the design system, represented in Yaml and parsed into other file templates (SCSS, JSON, etc.) as needed. Tokens are a shared resource meant to be accessed by engineering and design. Here is an example token file:</p>
<pre><code class="language-yml"># Colors.yml
# All colors used in the Lessonly application
metadata:
    type: color
props:
    brandBlue:
        friendlyName: 'Brand Blue'
        hex: '#4a90e2'
        hsl: '212, 72%, 59%'
        rgb: '74, 144, 226'
</code></pre>
<p>At some point in the future, Token files might be autogenerated from a Sketch file, but for now they are just edited by hand.</p>
<h4>Framework</h4>
<p>The Framework category of SCCSS is defines a number of global styles for use around our codebase. It is built in a modified version of <a href="https://itcss.io/">ITCSS</a> and is focused on making providing a platform to maintain consistency across the application. There are 4 sub-categories of files in this section:</p>
<h5>@ (ats or &quot;application tools and settings&quot;)</h5>
<p>Ats are the files related to creating tools and settings for use within other CSS files. They shouldn't output CSS of their own and instead should create <code>@mixin</code>s, <code>@includes</code> and <code>@imports</code> for other files. This also is where the SCSS token output is imported into the application. It also includes <a href="https://sass-lang.com/guide#topic-7"><code>%placeholders</code></a>, but they should be used sparingly and follow the <a href="https://en.wikipedia.org/wiki/Single_responsibility_principle">single responsibility principal</a>. Finally this is where any 3rd-party CSS should be imported.</p>
<h5>Generics</h5>
<p>This section includes any generic HTML styles that should appear in your application. This also includes any reset or normalization CSS. All selectors in this section should be basic HTML tags or attribute tags and should be relatively short. Here is where you would define default styles for things like <code>h1</code>s, <code>p</code>s, or <code>button</code>s.</p>
<h5>Objects</h5>
<p>Objects are reusable patterns that pop up around the application. Here we can find commonly used layouts like grids and lists, as well as things like the <a href="https://getbootstrap.com/docs/4.0/layout/media-object/">media object</a> or <a href="https://csswizardry.com/2013/05/the-flag-object/">flag object</a>. All classes that appear here should be prefixed with <code>.o-</code> and should be used in conjunction with their corresponding UI library elements. For example, <code>grid.scss</code> might contain:</p>
<pre><code class="language-scss">.o-Grid {
    display: grid;
    
    .o-Grid--threeCol {
        grid-template-columns: 1fr 1fr 1fr;
    }

    .o-Grid--fourCol {
        grid-template-columns: 1fr 1fr 1fr 1fr;
    }
}
</code></pre>
<p>This would be in conjunction with <code>Grid.js</code>, which might contain:</p>
<pre><code class="language-js">const Grid = ({columns = 'four', children}) =&gt; {
    return (
        &lt;div className={`o-Grid o-Grid--${columns}Col`}&gt;
            {children}
        &lt;/div&gt;
    )
}
</code></pre>
<h5>Utilities</h5>
<p>Utilities are simple CSS classes that are used to override other styles. They should follow the Single Reponsibility Principal and often will only contain one line of CSS. They may contain <code>!important</code> tags as they are supposed to override all CSS with the same properties. These classes might be helper classes, hacks or overrides and are often not incredibly elegant in their design. These classes should be prefix with <code>.u-</code>. An example might be a clearfix utility:</p>
<pre><code class="language-scss">    .u-clearfix {
        clearfix: both;
    }
</code></pre>
<h4>Components</h4>
<p>Finally, Components make up the building blocks of the application. These classes are individual, specific elements of the UI that make up the application. Components follow <a href="#extends--includes--styles--nested-styles">our formatting guidelines</a> and should be locally scoped, affecting only the CSS in thier own file. These files should be commented according the the <a href="#comment-class-usage">commenting guidelines</a> below. For example, the Button UI component might be defined as such:</p>
<pre><code class="language-scss">/*
  Button component

  .Button:hover         - Style for a Button that has been hovered
  .Button--default      - Default style for a Button
  .Button--inactive     - Inactive style for a Button
*/
.Button {
    &amp;.Button--default {
        background: $brand-blue;
        color: $white;
    }

    &amp;.Button--inactive {
        background: $brand-gray;
        color: $brand-gray-darker;
    }

    &amp;:hover {
        transform: translateX(-2px);
        box-shadow: $hover-box-shadow;
    }
}
</code></pre>
<h4>Putting it all together</h4>
<p>All of these piece working together allow us to write easy to read, understandable CSS that we can maintain simply. Here is a quick example of the Button class, using Tokens, the Framework, and a Component file.</p>
<pre><code class="language-scss">/*
  Button component

  .Button:hover         - Style for a Button that has been hovered
  .Button--inactive     - Inactive style for a Button
  .Button--default      - Default style for a Button
  .Button--gradient     - Gradient style for a Button
  .Button-text          - The text content of a Button
*/
.Button {
    // This button will be normalized across browsers from a setting in Framework/Generic
    // That means it is ready to be styled according to our needs

    // This button could be included in a layout established by the Framework/Object section
    // It's text-align or clearfix could be overwritting with a Framework/Utility class

    @extend %reset-button; // &lt;- using a placeholder defined in the Framework/ats section
    @include when-lang('ar') { // &lt;- language override imported from Frameworks/ats
        text-align: right;
    }

    text-align: left;

    &amp;.Button--default {
        background: $brand-blue; // &lt;- color variable imported in Framework/ats and defined in our tokens
        color: $white;
    }

    &amp;.Button--inactive {
        background: $brand-gray;
        color: $brand-gray-darker;
    }

    &amp;.Button--gradient {
        @include gradient-vertical($brand-purple, $brand-purple-dark); // &lt;- Gradient mixin defined in Framework/ats 
        color: $white;
    }

    .Button-text {
        font-size: $font-normal; // &lt;- Font size imported from Tokens
    }

    &amp;:hover {
        transform: translateX(-2px);
        box-shadow: $hover-box-shadow;
    }
}
</code></pre>