{"id":13495871,"url":"https://github.com/dropbox/css-style-guide","last_synced_at":"2025-04-13T11:47:42.239Z","repository":{"id":59462716,"uuid":"44996791","full_name":"dropbox/css-style-guide","owner":"dropbox","description":"Dropbox’s (S)CSS authoring style guide","archived":false,"fork":false,"pushed_at":"2019-11-08T08:25:39.000Z","size":11,"stargazers_count":1203,"open_issues_count":3,"forks_count":86,"subscribers_count":37,"default_branch":"master","last_synced_at":"2025-04-06T08:11:28.429Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dropbox.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-10-26T20:57:17.000Z","updated_at":"2025-04-05T07:21:16.000Z","dependencies_parsed_at":"2022-09-16T12:11:59.095Z","dependency_job_id":null,"html_url":"https://github.com/dropbox/css-style-guide","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dropbox%2Fcss-style-guide","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dropbox%2Fcss-style-guide/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dropbox%2Fcss-style-guide/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dropbox%2Fcss-style-guide/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dropbox","download_url":"https://codeload.github.com/dropbox/css-style-guide/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248710409,"owners_count":21149186,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T19:01:39.110Z","updated_at":"2025-04-13T11:47:42.215Z","avatar_url":"https://github.com/dropbox.png","language":null,"funding_links":[],"categories":["Others","CSS","Code Style Guidelines :book:","Style Guides"],"sub_categories":["Editor's Draft :black_nib:","Miscellaneous"],"readme":"# Dropbox (S)CSS Style Guide\n\n\u003e “Every line of code should appear to be written by a single person, no matter the number of contributors.” —@mdo\n\n## General\n### Don’ts\n\n- Avoid using HTML tags in CSS selectors\n  - E.g. Prefer `.o-modal {}` over `div.o-modal {}`\n  - Always prefer using a class over HTML tags (with some exceptions like CSS resets)\n- Don't use ids in selectors\n  - `#header` is overly specific compared to, for example `.header` and is much harder to override\n  - 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/).\n- Don’t nest more than 3 levels deep\n  - 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.\n- Avoid using nesting for anything other than pseudo selectors and state selectors.\n  - E.g. nesting `:hover`, `:focus`, `::before`, etc. is OK, but nesting selectors inside selectors should be avoided.\n- Don't `!important`\n  - Ever.\n  - If you must, leave a comment, and prioritise resolving specificity issues before resorting to `!important`.\n  - `!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.\n- Don’t use `margin-top`.\n  - 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\n- Avoid shorthand properties (unless you really need them)\n  - 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.”\n  - This applies to all properties with a shorthand: border, margin, padding, font, etc.\n\n### Spacing\n\n- Four spaces for indenting code\n- Put spaces after `:` in property declarations\n  - E.g. `color: red;` instead of `color:red;`\n- Put spaces before `{` in rule declarations\n  - E.g. `.o-modal {` instead of `.o-modal{`\n- Write your CSS one line per property\n- Add a line break after `}` closing rule declarations\n- When grouping selectors, keep individual selectors on a single line\n- Place closing braces `}` on a new line\n- Add a new line at the end of .scss files\n- Trim excess whitespace\n\n### Formatting\n\n- All selectors are lower case, hyphen separated aka “spinal case” eg. `.my-class-name`\n- Always prefer Sass’s double-slash `//` commenting, even for block comments\n- Avoid specifying units for zero values, e.g. `margin: 0;` instead of `margin: 0px;`\n- Always add a semicolon to the end of a property/value declaration\n- Use leading zeros for decimal values `opacity: 0.4;` instead of `opacity: .4;`\n- Put spaces before and after child selector `div \u003e span` instead of `div\u003espan`\n\n----------\n\n## Sass Specifics\n### Internal order of a .scss file\n\n1. Imports\n2. Variables\n3. Base Styles\n4. Experiment Styles\n\nExample:\n\n```scss\n//------------------------------\n// Modal\n//------------------------------\n\n@import \"../constants\";\n@import \"../helpers\";\n\n$DBmodal-namespace: \"c-modal\" !default;\n$DBmodal-padding: 32px;\n\n$DBmodal-background: #fff !default;\n$DBmodal-background-alt: color(gray, x-light) !default;\n\n.o-modal { ... }\n\n// Many lines later...\n\n// EXPERIMENT: experiment-rule-name\n.o-modal--experiment { ... }\n// END EXPERIMENT: experiment-rule-name\n```\n\n### Variables\n\n- Define all variables at the top of the file after the imports\n- Namespace local variables with the filename (SASS has no doc level scope)\n  - eg `business_contact.scss` →`$business_contact_font_size: 14px;`\n- Local variables should be `$snake_lowercase`\n- Global constants should be `$SNAKE_ALL_CAPS`\n\n### Color\n\n- Use the defined color constants via the color function\n- Lowercase all hex values `#fffff`\n- Limit alpha values to a maximum of two decimal places. Always use a leading zero.\n\nExample:\n\n```scss\n// Bad\n.c-link {\n  color: #007ee5;\n  border-color: #FFF;\n  background-color: rgba(#FFF, .0625);\n}\n\n// Good\n.c-link {\n  color: color(blue);\n  border-color: #ffffff;\n  background-color: rgba(#ffffff, 0.1);\n}\n```\n\n### Experiments\n\nWrap experiment styles with comments:\n\n```scss\n// EXPERIMENT: experiment-rule-name\n.stuff { ... }\n// END EXPERIMENT: experiment-rule-name\n```\n\n----------\n\n## Rule Ordering\n\nProperties and nested declarations should appear in the following order, with line breaks between groups:\n\n1. Any `@` rules\n2. Layout and box-model properties\n  - margin, padding, box-sizing, overflow, position, display, width/height, etc.\n3. Typographic properties\n  - E.g. font-*, line-height, letter-spacing, text-*, etc.\n4. Stylistic properties\n  - color, background-*, animation, border, etc.\n5. UI properties\n  - appearance, cursor, user-select, pointer-events, etc.\n6. Pseudo-elements\n  - ::after, ::before, ::selection, etc.\n7. Pseudo-selectors\n  - :hover, :focus, :active, etc.\n8. Modifier classes\n9. Nested elements\n\nHere’s a comprehensive example:\n\n```scss\n.c-btn {\n    @extend %link--plain;\n\n    display: inline-block;\n    padding: 6px 12px;\n\n    text-align: center;\n    font-weight: 600;\n\n    background-color: color(blue);\n    border-radius: 3px;\n    color: white;\n\n    \u0026::before {\n        content: '';\n    }\n\n    \u0026:focus, \u0026:hover {\n        box-shadow: 0 0 0 1px color(blue, .3);\n    }\n\n    \u0026--big {\n        padding: 12px 24px;\n    }\n\n    \u003e .c-icon {\n        margin-right: 6px;\n    }\n}\n```\n\n----------\n\n## Nesting\n\n- As a general rule of thumb, avoid nesting selectors more than 3 levels deep\n- Prefer using nesting as a convenience to extend the parent selector over targeting nested elements. For example:\n  ```scss\n  .block {\n      padding: 24px;\n\n      \u0026--mini {\n          padding: 12px;\n      }\n  }\n  ```\n\nNesting can be really easily avoided by smart class naming (with the help of BEM) and avoiding bare tag selectors.\n\n----------\n\n## BEM\n\nBlock: Unique, meaningful names for a logical unit of style. Avoid excessive shorthand.\n- Good: `.alert-box` or `.recents-intro` or `.button`\n- Bad: `.feature` or `.content` or `.btn`\n\nElement: 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:\n- `.alert-box__close`\n- `.expanding-section__section`\n\nModifier: 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:\n- `.alert-box--success`\n- `.expanding-section--expanded`\n\n### BEM Best practices\n\nDon't `@extend` block modifiers with the block base.\n- Good: `\u003cdiv class=\"my-block my-block--modifier\"\u003e`\n- Bad: `\u003cdiv class=\"my-block--modifier\"\u003e`\n\nDon't create elements inside elements. If you find yourself needing this, consider converting your element into a block.\n- Bad: `.alert-box__close__button`\n\nChoose your modifiers wisely. These two rules have very different meaning:\n\n```scss\n.block--modifier .block__element { color: red; }\n.block__element--modifier { color: red; }\n```\n\n----------\n\n## Selector Naming\n\n- Try to use [BEM-based](http://csswizardry.com/2013/01/mindbemding-getting-your-head-round-bem-syntax/) naming for your class selectors\n  - When using modifier classes, always require the base/unmodified class is present\n- Use Sass’s nesting to manage BEM selectors like so:\n  ```scss\n  .block {\n      \u0026--modifier { // compiles to .block--modifier\n          text-align: center;\n      }\n\n      \u0026__element { // compiles to .block__element\n          color: red;\n\n          \u0026--modifier { // compiles to .block__element--modifier\n              color: blue;\n          }\n      }\n  }\n  ```\n\n----------\n\n## Namespaced Classes\n\nThere are a few reserved namespaces for classes to provide common and globally-available abstractions.\n\n- `.o-` for CSS objects. Objects are usually common design patterns (like the Flag object). Modifying these classes could have severe knock-on effects.\n- `.c-` for CSS components. Components are designed pieces of UI—think buttons, inputs, modals, and banners.\n- `.u-` for helpers and utilities. Utility classes are usually single-purpose and have high priority. Things like floating elements, trimming margins, etc.\n- `.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.\n- `._` 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.\n- `.t-` for theme classes. Pages with unique styles or overrides for any objects or components should make use of theme classes.\n\n----------\n\n## Separation of Concerns (One Thing Well™)\n\nYou 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.\n\n```scss\n// Bad code\n// HTML:\n// \u003cdiv class=\"modal compact\"\u003e...\u003c/div\u003e\n.modal {\n    padding: 32px;\n    background-color: color(gray, x-light);\n\n    \u0026.compact {\n        padding: 24px;\n    }\n}\n\n// Good code\n// HTML:\n// \u003cdiv class=\"c-modal u-l-island\"\u003e...\u003c/div\u003e\n// \u003cdiv class=\"c-modal u-l-isle\"\u003e...\u003c/div\u003e\n\n// components/_modal.scss\n.c-modal {\n    background-color: color(gray, x-light);\n}\n\n// helpers/_layout.scss\n.u-l-island {\n    padding: 32px;\n}\n\n.u-l-isle {\n    padding: 24px;\n}\n```\n\n----------\n\n## Media Queries\n\nMedia queries should be within the CSS selector as per SMACSS\n\n```scss\n.selector {\n      float: left;\n\n      @media only screen and (max-width: 767px) {\n        float: none;\n      }\n}\n```\n\nCreate variables for frequently used breakpoints\n\n```scss\n$SCREEN_SM_MAX: \"max-width: 767px\";\n\n.selector {\n      float: left;\n\n      @media only screen and ($SCREEN_SM_MAX) {\n        float: none;\n      }\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdropbox%2Fcss-style-guide","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdropbox%2Fcss-style-guide","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdropbox%2Fcss-style-guide/lists"}