Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/dropbox/css-style-guide
Dropbox’s (S)CSS authoring style guide
https://github.com/dropbox/css-style-guide
Last synced: 20 days ago
JSON representation
Dropbox’s (S)CSS authoring style guide
- Host: GitHub
- URL: https://github.com/dropbox/css-style-guide
- Owner: dropbox
- License: other
- Created: 2015-10-26T20:57:17.000Z (about 9 years ago)
- Default Branch: master
- Last Pushed: 2019-11-08T08:25:39.000Z (almost 5 years ago)
- Last Synced: 2024-09-30T12:20:48.165Z (about 1 month ago)
- Size: 10.7 KB
- Stars: 1,161
- Watchers: 38
- Forks: 82
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- License: LICENSE.md
Awesome Lists containing this project
README
# Dropbox (S)CSS Style Guide
> “Every line of code should appear to be written by a single person, no matter the number of contributors.” —@mdo
## General
### Don’ts- Avoid using HTML tags in CSS selectors
- E.g. Prefer `.o-modal {}` over `div.o-modal {}`
- Always prefer using a class over HTML tags (with some exceptions like CSS resets)
- Don't use ids in selectors
- `#header` is overly specific compared to, for example `.header` and is much harder to override
- Read more about the headaches associated with IDs in CSS [here](http://csswizardry.com/2011/09/when-using-ids-can-be-a-pain-in-the-class/).
- Don’t nest more than 3 levels deep
- 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.
- Avoid using nesting for anything other than pseudo selectors and state selectors.
- E.g. nesting `:hover`, `:focus`, `::before`, etc. is OK, but nesting selectors inside selectors should be avoided.
- Don't `!important`
- Ever.
- If you must, leave a comment, and prioritise resolving specificity issues before resorting to `!important`.
- `!important` greatly increases the power of a CSS declaration, making it extremely tough to override in the future. It’s only possible to override with another `!important` declaration later in the cascade.
- Don’t use `margin-top`.
- Vertical margins [collapse](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Box_Model/Mastering_margin_collapsing). Always prefer `padding-top` or`margin-bottom` on preceding elements
- Avoid shorthand properties (unless you really need them)
- 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.”
- This applies to all properties with a shorthand: border, margin, padding, font, etc.### Spacing
- Four spaces for indenting code
- Put spaces after `:` in property declarations
- E.g. `color: red;` instead of `color:red;`
- Put spaces before `{` in rule declarations
- E.g. `.o-modal {` instead of `.o-modal{`
- Write your CSS one line per property
- Add a line break after `}` closing rule declarations
- When grouping selectors, keep individual selectors on a single line
- Place closing braces `}` on a new line
- Add a new line at the end of .scss files
- Trim excess whitespace### Formatting
- All selectors are lower case, hyphen separated aka “spinal case” eg. `.my-class-name`
- Always prefer Sass’s double-slash `//` commenting, even for block comments
- Avoid specifying units for zero values, e.g. `margin: 0;` instead of `margin: 0px;`
- Always add a semicolon to the end of a property/value declaration
- Use leading zeros for decimal values `opacity: 0.4;` instead of `opacity: .4;`
- Put spaces before and after child selector `div > span` instead of `div>span`----------
## Sass Specifics
### Internal order of a .scss file1. Imports
2. Variables
3. Base Styles
4. Experiment StylesExample:
```scss
//------------------------------
// Modal
//------------------------------@import "../constants";
@import "../helpers";$DBmodal-namespace: "c-modal" !default;
$DBmodal-padding: 32px;$DBmodal-background: #fff !default;
$DBmodal-background-alt: color(gray, x-light) !default;.o-modal { ... }
// Many lines later...
// EXPERIMENT: experiment-rule-name
.o-modal--experiment { ... }
// END EXPERIMENT: experiment-rule-name
```### Variables
- Define all variables at the top of the file after the imports
- Namespace local variables with the filename (SASS has no doc level scope)
- eg `business_contact.scss` →`$business_contact_font_size: 14px;`
- Local variables should be `$snake_lowercase`
- Global constants should be `$SNAKE_ALL_CAPS`### Color
- Use the defined color constants via the color function
- Lowercase all hex values `#fffff`
- Limit alpha values to a maximum of two decimal places. Always use a leading zero.Example:
```scss
// Bad
.c-link {
color: #007ee5;
border-color: #FFF;
background-color: rgba(#FFF, .0625);
}// Good
.c-link {
color: color(blue);
border-color: #ffffff;
background-color: rgba(#ffffff, 0.1);
}
```### Experiments
Wrap experiment styles with comments:
```scss
// EXPERIMENT: experiment-rule-name
.stuff { ... }
// END EXPERIMENT: experiment-rule-name
```----------
## Rule Ordering
Properties and nested declarations should appear in the following order, with line breaks between groups:
1. Any `@` rules
2. Layout and box-model properties
- margin, padding, box-sizing, overflow, position, display, width/height, etc.
3. Typographic properties
- E.g. font-*, line-height, letter-spacing, text-*, etc.
4. Stylistic properties
- color, background-*, animation, border, etc.
5. UI properties
- appearance, cursor, user-select, pointer-events, etc.
6. Pseudo-elements
- ::after, ::before, ::selection, etc.
7. Pseudo-selectors
- :hover, :focus, :active, etc.
8. Modifier classes
9. Nested elementsHere’s a comprehensive example:
```scss
.c-btn {
@extend %link--plain;display: inline-block;
padding: 6px 12px;text-align: center;
font-weight: 600;background-color: color(blue);
border-radius: 3px;
color: white;&::before {
content: '';
}&:focus, &:hover {
box-shadow: 0 0 0 1px color(blue, .3);
}&--big {
padding: 12px 24px;
}> .c-icon {
margin-right: 6px;
}
}
```----------
## Nesting
- As a general rule of thumb, avoid nesting selectors more than 3 levels deep
- Prefer using nesting as a convenience to extend the parent selector over targeting nested elements. For example:
```scss
.block {
padding: 24px;&--mini {
padding: 12px;
}
}
```Nesting can be really easily avoided by smart class naming (with the help of BEM) and avoiding bare tag selectors.
----------
## BEM
Block: Unique, meaningful names for a logical unit of style. Avoid excessive shorthand.
- Good: `.alert-box` or `.recents-intro` or `.button`
- Bad: `.feature` or `.content` or `.btn`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. Examples:
- `.alert-box__close`
- `.expanding-section__section`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. Examples:
- `.alert-box--success`
- `.expanding-section--expanded`### BEM Best practices
Don't `@extend` block modifiers with the block base.
- Good: ``
- Bad: ``Don't create elements inside elements. If you find yourself needing this, consider converting your element into a block.
- Bad: `.alert-box__close__button`Choose your modifiers wisely. These two rules have very different meaning:
```scss
.block--modifier .block__element { color: red; }
.block__element--modifier { color: red; }
```----------
## Selector Naming
- Try to use [BEM-based](http://csswizardry.com/2013/01/mindbemding-getting-your-head-round-bem-syntax/) naming for your class selectors
- When using modifier classes, always require the base/unmodified class is present
- Use Sass’s nesting to manage BEM selectors like so:
```scss
.block {
&--modifier { // compiles to .block--modifier
text-align: center;
}&__element { // compiles to .block__element
color: red;&--modifier { // compiles to .block__element--modifier
color: blue;
}
}
}
```----------
## Namespaced Classes
There are a few reserved namespaces for classes to provide common and globally-available abstractions.
- `.o-` for CSS objects. Objects are usually common design patterns (like the Flag object). Modifying these classes could have severe knock-on effects.
- `.c-` for CSS components. Components are designed pieces of UI—think buttons, inputs, modals, and banners.
- `.u-` for helpers and utilities. Utility classes are usually single-purpose and have high priority. Things like floating elements, trimming margins, etc.
- `.is-, .has-` for stateful classes, a la [SMACSS](https://smacss.com/book/type-state). Use these classes for temporary, optional, or short-lived states and styles.
- `._` 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.
- `.t-` for theme classes. Pages with unique styles or overrides for any objects or components should make use of theme classes.----------
## Separation of Concerns (One Thing Well™)
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.
```scss
// Bad code
// HTML:
//...
.modal {
padding: 32px;
background-color: color(gray, x-light);&.compact {
padding: 24px;
}
}// Good code
// HTML:
//...
//...// components/_modal.scss
.c-modal {
background-color: color(gray, x-light);
}// helpers/_layout.scss
.u-l-island {
padding: 32px;
}.u-l-isle {
padding: 24px;
}
```----------
## Media Queries
Media queries should be within the CSS selector as per SMACSS
```scss
.selector {
float: left;@media only screen and (max-width: 767px) {
float: none;
}
}
```Create variables for frequently used breakpoints
```scss
$SCREEN_SM_MAX: "max-width: 767px";.selector {
float: left;@media only screen and ($SCREEN_SM_MAX) {
float: none;
}
}
```