Skip to content

Commit 99a91f8

Browse files
committed
Initial commit
0 parents  commit 99a91f8

File tree

1 file changed

+397
-0
lines changed

1 file changed

+397
-0
lines changed

README.md

Lines changed: 397 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,397 @@
1+
# Dropbox (S)CSS Style Guide
2+
3+
> “Every line of code should appear to be written by a single person, no matter the number of contributors.” —@mdo
4+
5+
## General
6+
### Don’ts
7+
8+
- Avoid using HTML tags in CSS selectors
9+
- E.g. Prefer `.o-modal {}` over `div.o-modal {}`
10+
- Always prefer using a class over HTML tags (with some exceptions like CSS resets)
11+
- Don't use ids in selectors
12+
- `#header` is overly specific compared to, for example `.header` and is much harder to override
13+
- Read more about the headaches associated with IDs in CSS here.
14+
- Don’t nest more than 3 levels deep
15+
- Nesting selectors increases specificity, meaning that overriding any CSS set therein needs to be targeted with an even more specific selector. This quickly becomes a significant maintenance issue.
16+
- Avoid using nesting for anything other than pseudo selectors and state selectors.
17+
- E.g. nesting `:hover`, `:focus`, `::before`, etc. is OK, but nesting selectors inside selectors should be avoided.
18+
- Don't `!important`
19+
- Ever.
20+
- If you must, leave a comment, and prioritise resolving specificity issues before resorting to `!important`.
21+
- `!important` greatly increases the power of a CSS rule, making it extremely tough to override in the future. It’s only possible to override with another `!important` rule later in the cascade.
22+
- Don’t use `margin-top`.
23+
- Vertical margins collapse. Always prefer `padding-top` or`margin-bottom` on preceding elements
24+
- Avoid shorthand properties (unless you really need them)
25+
- It can be tempting to use, for instance, `background: #fff` instead of `background-color: #fff`, but doing so overrides other values encapsulated by the shorthand property. (In this case, `background-image` and its associative properties are set to “none.”
26+
- This applies to all properties with a shorthand: border, margin, padding, font, etc.
27+
28+
### Spacing
29+
30+
- Four spaces for indenting code
31+
- Put spaces after `:` in property declarations
32+
- E.g. `color: red;` instead of `color:red;`
33+
- Put spaces before `{` in rule declarations
34+
- E.g. `.o-modal {` instead of `.o-modal{`
35+
- Write your CSS one line per rule
36+
- Add a line break after `}` closing rule declarations
37+
- When grouping selectors, keep individual selectors on a single line
38+
- Place closing braces `}` on a new line
39+
- Add a new line at the end of .scss files
40+
- Trim excess whitespace
41+
42+
### Formatting
43+
44+
- All selectors are lower case, hyphen separated aka “spinal case” eg. `.my-class-name`
45+
- Always prefer Sass’s double-slash `//` commenting, even for block comments
46+
- Avoid specifying units for zero values, e.g. `margin: 0;` instead of `margin: 0px;`
47+
- Always add a semicolon to the end of a property/value rule
48+
- Use leading zeros for decimal values `opacity: 0.4;` instead of `opacity: .4;`
49+
- Put spaces before and after child selector `div > span` instead of `div>span`
50+
51+
----------
52+
53+
## Sass Specifics
54+
### Internal order of a .scss file
55+
56+
1. Imports
57+
2. Variables
58+
3. Base Styles
59+
4. Experiment Styles
60+
61+
Example:
62+
63+
```scss
64+
//------------------------------
65+
// Modal
66+
//------------------------------
67+
68+
@import "../constants";
69+
@import "../helpers";
70+
71+
$DBmodal-namespace: "c-modal" !default;
72+
$DBmodal-padding: 32px;
73+
74+
$DBmodal-background: #fff !default;
75+
$DBmodal-background-alt: color(gray, x-light) !default;
76+
77+
.o-modal { ... }
78+
// Many lines later...
79+
// EXPERIMENT: gandalf-rule-name
80+
.o-modal--experiment { ... }
81+
// END EXPERIMENT: gandalf-rule-name
82+
```
83+
84+
### Variables
85+
86+
- Define all variables at the top of the file after the imports
87+
- Namespace local variables with the filename (SASS has no doc level scope)
88+
- eg `business_contact.scss``$business_contact_font_size: 14px;`
89+
- Local variables should be `$snake_lowercase`
90+
- Global constants should be `$SNAKE_ALL_CAPS`
91+
92+
### Color
93+
94+
- Use the defined color constants via the color function
95+
- Lowercase all hex values `#fffff`
96+
- Limit alpha values to a maximum of two decimal places. Always use a leading zero.
97+
98+
Example:
99+
100+
```scss
101+
// Bad
102+
.c-link {
103+
color: #007ee5;
104+
border-color: #FFF;
105+
background-color: rgba(#FFF, .0625);
106+
}
107+
108+
// Good
109+
.c-link {
110+
color: color(blue);
111+
border-color: #ffffff;
112+
background-color: rgba(#ffffff, 0.1);
113+
}
114+
```
115+
116+
### Experiments
117+
118+
- Wrap experiment styles with comments:
119+
```scss
120+
// EXPERIMENT: gandalf-rule-name
121+
.stuff { ... }
122+
// END EXPERIMENT: gandalf-rule-name
123+
```
124+
125+
----------
126+
127+
## Rule Ordering
128+
129+
Properties and nested declarations should appear in the following order, with line breaks between groups:
130+
131+
1. Any `@` rules
132+
2. Layout and box-model properties
133+
- margin, padding, box-sizing, overflow, position, display, width/height, etc.
134+
3. Typographic properties
135+
- E.g. font-*, line-height, letter-spacing, text-*, etc.
136+
4. Stylistic properties
137+
- color, background-*, animation, border, etc.
138+
5. UI properties
139+
- appearance, cursor, user-select, pointer-events, etc.
140+
6. Pseudo-elements
141+
- ::after, ::before, ::selection, etc.
142+
7. Pseudo-selectors
143+
- :hover, :focus, :active, etc.
144+
8. Modifier classes
145+
9. Nested elements
146+
147+
Here’s a comprehensive example:
148+
149+
```scss
150+
.c-btn {
151+
@extend %link--plain;
152+
153+
display: inline-block;
154+
padding: 6px 12px;
155+
156+
text-align: center;
157+
font-weight: 600;
158+
159+
background-color: color(blue);
160+
border-radius: 3px;
161+
color: white;
162+
163+
&::before {
164+
content: '';
165+
}
166+
167+
&:focus, &:hover {
168+
box-shadow: 0 0 0 1px color(blue, .3);
169+
}
170+
171+
&--big {
172+
padding: 12px 24px;
173+
}
174+
175+
> .c-icon {
176+
margin-right: 6px;
177+
}
178+
}
179+
```
180+
181+
----------
182+
183+
## Nesting
184+
185+
- As a general rule of thumb, avoid nesting selectors more than 3 levels deep
186+
- Prefer using nesting as a convenience to extend the parent selector over targeting nested elements. For example:
187+
```scss
188+
.block {
189+
padding: 24px;
190+
191+
&--mini {
192+
padding: 12px;
193+
}
194+
}
195+
```
196+
197+
Nesting can be really easily avoided by smart class naming (with the help of BEM) and avoiding bare tag selectors.
198+
199+
----------
200+
201+
## BEM
202+
203+
Block: Unique, meaningful names for a logical unit of style. Avoid excessive shorthand.
204+
Good: ".alert-box" or ".expanding-section" or ".button"
205+
Bad: ".feature" or ".content" or ".btn"
206+
207+
Element: styles that only apply to children of a block. Elements can also be blocks themselves. Class name is a concatenation of the block name, two underscores and the element name.
208+
Examples:
209+
".alert-box__close"
210+
".expanding-section__section"
211+
212+
Modifier: override or extend the base styles of a block or element with modifier styles. Class name is a concatenation of the block (or element) name, two hyphens and the modifier name.
213+
Examples:
214+
".alert-box--success"
215+
".expanding-section--expanded"
216+
217+
### BEM Best practices
218+
219+
Don't `@extend` block modifiers with the block base.
220+
- Good: `<div class="my-block my-block--modifier">`
221+
- Bad: `<div class="my-block--modifier">`
222+
223+
Don't create elements inside elements. If you find yourself needing this, consider converting your element into a block.
224+
- Bad: `.alert-box__close__button`
225+
226+
Choose your modifiers wisely. These two rules have very different meaning:
227+
228+
```scss
229+
.block--modifier .block__element { color: red; }
230+
.block__element--modifier { color: red; }
231+
```
232+
233+
----------
234+
235+
## Selector Naming
236+
237+
- Try to use BEM-based naming for your class selectors
238+
- When using modifier classes, always require the base/unmodified class is present
239+
- Use Sass’s nesting to manage BEM selectors like so:
240+
```scss
241+
.block {
242+
&--modifier { // compiles to .block--modifier
243+
text-align: center;
244+
}
245+
246+
&__element { // compiles to .block__element
247+
color: red;
248+
249+
&--modifier { // compiles to .block__element--modifier
250+
color: blue;
251+
}
252+
}
253+
}
254+
```
255+
256+
----------
257+
258+
## Namespaced Classes
259+
260+
There are a few reserved namespaces for classes to provide common and globally-available abstractions.
261+
262+
- `.o-` for CSS objects. Objects are usually common design patterns (like the Flag object). Modifying these classes could have severe knock-on effects.
263+
- `.c-` for CSS components. Components are designed pieces of UI—think buttons, inputs, modals, and banners.
264+
- `.u-` for helpers and utilities. Utility classes are usually single-purpose and have high priority. Things like floating elements, trimming margins, etc.
265+
- `.is-, .has-` for stateful classes, a la SMACSS. Use these classes for temporary, optional, or short-lived states and styles.
266+
- `._` for hacks. Classes with a hack namespace should be used when you need to force a style with `!important` or increasing specificity, should be temporary, and should not be bound onto.
267+
- `.t-` for theme classes. Pages with unique styles or overrides for any objects or components should make use of theme classes.
268+
269+
----------
270+
271+
## Separation of Concerns (One Thing Well™)
272+
273+
You should always try to spot common code—padding, font sizes, layout patterns—and abstract them to reusable, namespaced classes that can be chained to elements and have a single responsibility. Doing so helps prevent overrides and duplicated rules, and encourages a separation of concerns.
274+
275+
```scss
276+
// Bad code
277+
// HTML:
278+
// <div class="modal compact">...</div>
279+
.modal {
280+
padding: 32px;
281+
background-color: color(gray, x-light);
282+
283+
&.compact {
284+
padding: 24px;
285+
}
286+
}
287+
288+
// Good code
289+
// HTML:
290+
// <div class="c-modal u-l-island">...</div>
291+
// <div class="c-modal u-l-isle">...</div>
292+
293+
// components/_modal.scss
294+
.c-modal {
295+
background-color: color(gray, x-light);
296+
}
297+
298+
// helpers/_layout.scss
299+
.u-l-island {
300+
padding: 32px;
301+
}
302+
303+
.u-l-isle {
304+
padding: 24px;
305+
}
306+
```
307+
308+
----------
309+
310+
## Media Queries
311+
312+
Media queries should be within the CSS selector as per SMACSS
313+
314+
```scss
315+
.selector {
316+
float: left;
317+
318+
@media only screen and (max-width: 767px) {
319+
float: none;
320+
}
321+
}
322+
```
323+
324+
Create variables for frequently used breakpoints
325+
326+
```scss
327+
$SCREEN_SM_MAX: "max-width: 767px";
328+
329+
.selector {
330+
float: left;
331+
332+
@media only screen and ($SMALL_BELOW) {
333+
float: none;
334+
}
335+
}
336+
```
337+
338+
Avoid revoking declarations in media queries
339+
340+
```scss
341+
// ----------------
342+
// Bad code:
343+
// ----------------
344+
.selector {
345+
display: inline-block;
346+
padding: 16px 20px;
347+
width: 50%;
348+
border: 1px solid color(blue, light);
349+
350+
@media only screen and ($SMALL_BELOW) {
351+
display: block;
352+
padding: 12px 16px;
353+
width: initial; // bad: forced to reset properties not used in this query
354+
}
355+
}
356+
357+
// Output:
358+
@media only screen and (min-width: 800px) {
359+
.selector {
360+
display: inline-block;
361+
padding: 16px 20px;
362+
width: 50%;
363+
border: 1px solid #5eb0f0;
364+
display: block;
365+
padding: 12px 16px;
366+
width: initial;
367+
}
368+
}
369+
370+
// ----------------
371+
// Good code:
372+
// ----------------
373+
.selector {
374+
border: 1px solid color(blue, light);
375+
376+
@media only screen and ($SMALL_BELOW) {
377+
display: block;
378+
padding: 12px 16px;
379+
width: auto;
380+
}
381+
382+
@media only screen and ($SMALL_ABOVE) {
383+
display: inline-block;
384+
padding: 16px 20px;
385+
}
386+
}
387+
388+
// Output:
389+
@media only screen and (min-width: 800px) {
390+
.selector {
391+
display: block;
392+
padding: 12px 16px;
393+
width: initial;
394+
border: 1px solid #5eb0f0;
395+
}
396+
}
397+
```

0 commit comments

Comments
 (0)