{"id":13564407,"url":"https://github.com/sky-uk/css","last_synced_at":"2025-04-05T00:07:39.281Z","repository":{"id":57362491,"uuid":"74592011","full_name":"sky-uk/css","owner":"sky-uk","description":"Believe in Better CSS","archived":false,"fork":false,"pushed_at":"2018-12-05T10:34:57.000Z","size":32,"stargazers_count":279,"open_issues_count":0,"forks_count":9,"subscribers_count":141,"default_branch":"master","last_synced_at":"2025-03-28T23:06:12.657Z","etag":null,"topics":["css","guide","sass","scss","sky","styleguide","stylesheets"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sky-uk.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-11-23T15:58:02.000Z","updated_at":"2024-10-25T09:09:15.000Z","dependencies_parsed_at":"2022-09-26T16:32:10.414Z","dependency_job_id":null,"html_url":"https://github.com/sky-uk/css","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sky-uk%2Fcss","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sky-uk%2Fcss/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sky-uk%2Fcss/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sky-uk%2Fcss/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sky-uk","download_url":"https://codeload.github.com/sky-uk/css/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247266563,"owners_count":20910836,"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":["css","guide","sass","scss","sky","styleguide","stylesheets"],"created_at":"2024-08-01T13:01:30.867Z","updated_at":"2025-04-05T00:07:39.259Z","avatar_url":"https://github.com/sky-uk.png","language":"JavaScript","readme":"# Sky CSS Style Guide\n\n\u003e Believe in Better CSS\n\nAn Evolving CSS / Sass Style Guide for Sky\n\n## Contents\n\n### Writing CSS / Sass\n\n* [Template](#template)\n* [Architecture](#architecture)\n* [Formatting](#formatting)\n* [Selectors and Naming](#selectors-and-naming)\n* [Properties](#properties)\n* [Extending and Modifying](#extending-and-modifying)\n* [Specificity](#specificity)\n* [Resources](#resources)\n\n### Linter\n\n* [Installation](#installation)\n* [Versioning](#versioning)\n* [Maintainers](#maintainers)\n\n---\n\n## Writing CSS / Sass\n\n### Template\n\nBefore diving into the details of CSS coding style, you can find a Sky-conformant `.scss` template over at [git.io/template](https://git.io/template).\n\nInstantly get started with:\n\n```\ncurl -L git.io/template -o _\u003cyour-file-name\u003e.scss\n```\n\n[⬆ Back to contents](#contents)\n\n### Architecture\n\nProject stylesheets should be structured following closely to the principles of [ITCSS](https://medium.com/@jordankoschei/how-i-shrank-my-css-by-84kb-by-refactoring-with-itcss-2e8dafee123a#.7gdzbrk1m), imported in the following order for greater control over re-usability and specificity:\n\n0. **Settings** - Global configuration and variables.\n0. **Tools** - Mixins and functions.\n0. **Generic** - High-level styles such as resets and [normalize.css](https://github.com/necolas/normalize.css).\n0. **Elements** - Base HTML styling.\n0. **Objects** - Common non-cosmetic structural design patterns.\n0. **Components** - Specific cosmetic elements of UI.\n0. ~~Trumps~~ **Utilities** - Helpers and overrides.\n\n[⬆ Back to contents](#contents)\n\n### Formatting\n\n* Use soft tabs (**2** spaces) for indentation.\n* Use lower-case hyphenated naming over camelCase.\n* Put a space before an opening bracket `{` and a new line after.\n* Put a new line before and after a closing bracket `}`.\n* Put a space after, but not before, a colon `:`.\n* Put a new line after a semi-colon `;`, with no space before.\n* Don't leave more than **1** line empty.\n* Use `// comment` commenting for non-outputted SCSS (e.g. settings, functions).\n* Use `/* comment */` commenting for all other SCSS\n  * Outputted comments are useful for debugging, and can always be removed later in production using various build tools.\n* Leave an empty line at the end of a file.\n* Use leading zeros for decimal values (e.g. `0.5` instead of `.5`) for better readability.\n* Don't specify units for zero values (e.g. `0` instead of `0px`).\n\n[⬆ Back to contents](#contents)\n\n### Selectors and Naming\n\nIt's important we keep code transparent and self-documented when it comes to naming our selectors.\n\n:x: **Don't**\n\n* **Don't** use `html` tags in selectors.\n* **Don't** use IDs (`#`) in selectors.\n* **Don't** unnecessarily nest selectors.\n  * Try to keep selectors flat, at the same level of specificity.\n  * Avoid going more than 2 levels deep.\n\n:white_check_mark: **Do**\n\n* **Do** use classes.\n\n[⬆ Back to contents](#contents)\n\n#### BEM\n\n**B**lock, **E**lement, **M**odifier\n\n[BEM](http://getbem.com/naming/) is naming convention that aims to improve readability and re-usability.\n\nAll CSS class names should follow the BEM pattern.\n\n##### Block\n\nA block represents an independent component and should **specifically** describe its purpose.\n\n```html\n\u003cdiv class=\"block\"\u003e\u003c/div\u003e\n```\n\nFor more detail on BEM blocks, visit [bem.info](https://en.bem.info/methodology/quick-start/#block).\n\n##### Element\n\nElements represent parts of a block and cannot be used separately, they have no standalone meaning.\n\nAn element should be named to describe its purpose, prefixed with a double underscore `__` to separate from the block.\n\n```html\n\u003cdiv class=\"block\"\u003e\n  \u003cdiv class=\"block__element\"\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\n```\n\nIn your stylesheet this would look like:\n\n```scss\n.block {\n  /* block styles here */\n}\n\n.block__element {\n  /* element styles here */\n}\n```\n\nAvoid using the SCSS ampersand shortcut (`\u0026__`) when defining elements, it'll make searching your codebase a lot less productive.\n\n:warning: **Don't** create elements inside elements (e.g. `.block__element__element`). Consider creating a new block for the parent element instead.\n\nFor more detail on BEM\nelements, visit [bem.info](https://en.bem.info/methodology/quick-start/#element).\n\n##### Modifier\n\nModifiers define a change in cosmetics, used alongside a block or element.\n\nChanges in a state shouldn't be dictated by modifiers, and are handled [slightly differently](#states).\n\nA modifier should be named to describe its purpose, prefixed with a double hyphen `--` to separate from the block or element.\n\n```html\n\u003cdiv class=\"block block--modifier\"\u003e\n  \u003cdiv class=\"block__element\"\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\n```\n\nand / or\n\n```html\n\u003cdiv class=\"block\"\u003e\n  \u003cdiv class=\"block__element block__element--modifier\"\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\n```\n\nIn your stylesheet this would look like:\n\n```scss\n.block {\n  /* block styles here */\n}\n\n.block--modifier {\n  /* modifier styles here */\n}\n```\n\nAvoid using the SCSS ampersand shortcut (`\u0026--`) when defining elements, it'll make searching your codebase a lot less productive.\n\nFor more detail on BEM\nmodifiers, visit [bem.info](https://en.bem.info/methodology/quick-start/#modifier).\n\n#### States\n\n* `is-`\n* `has-`\n\nState prefixes signify that the piece of UI in question is currently styled a certain way because of a [state or condition](https://smacss.com/book/type-state). It tells us that the DOM currently has a temporary, optional, or short-lived style applied to it due to a certain state being invoked.\n\n```html\n\u003cdiv class=\"c-example is-active\"\u003e\u003c/div\u003e\n```\n\nor\n\n```html\n\u003cdiv class=\"c-example\"\u003e\n  \u003cdiv class=\"c-example__element is-active\"\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\n```\n\n#### Namespacing\n\nFollowing a prefix convention provides better insight into a class' purpose for other developers to work with.\n\n* `o-` signifies that this class is an **Object**, and that it may be used in any number of unrelated contexts to the one you can currently see it in. :warning: Making modifications to these types of class could potentially have knock-on effects in a lot of other unrelated places.\n* `c-` signifies that this class is a **Component**. This is a concrete, implementation-specific piece of UI. All of the changes you make to its styles should be detectable in the context you're currently looking at. Modifying on top of these styles should be safe and have no side effects.\n* `u-` signifies that this class is a **Utility** class. It has a very specific role (often providing only one declaration) and should not be bound onto or changed. It can be reused and is not tied to any specific piece of UI. You will probably recognise this namespace from libraries and methodologies like SUIT.\n* `t-` signifies that a class is responsible for adding a **Theme** to a view. It lets us know that UI Components' current cosmetic appearance may be due to the presence of a theme.\n* `js-` signifies that this piece of the DOM has some **behaviour** acting upon it, and that JavaScript binds onto it to provide that behaviour. If you're not a developer working with JavaScript, leave these well alone.\n* `qa-` signifies that a **QA or Test Engineering** team is running an automated UI test which needs to find or bind onto these parts of the DOM. Like the JavaScript namespace, this reserves hooks in the DOM for non-CSS purposes.\n\n[⬆ Back to contents](#contents)\n\n### Properties\n\nProperties should be ordered in the following manner (a style similar to [Dropbox](https://github.com/dropbox/css-style-guide#rule-ordering)) to promote readability:\n\n0. **@include** - use your previously-defined mixins right at the start for ease of modification and readability.\n0. **Structure** - `display`, `position`, `margin`, `padding`, `width`, `height`, `box-sizing`, `overflow` etc.\n0. **Typography** - `font-*`, `line-height`, `text-*`, `letter-spacing` etc.\n0. **Cosmetic** - `color`, `background-*`, `border-*`, `animation`, `transition` etc.\n0. **Native interaction** - `appearance`, `cursor`, `user-select`, `pointer-events` etc.\n0. **Pseudo-elements** - `::before`, `::after` etc.\n0. **Nested elements**\n0. **Pseudo-classes** - `:hover`, `:focus`, `:active` etc.\n0. **@media** - media queries should be defined last for ease of modification and readability.\n\nDefining separately:\n\n0. [**State classes**](#states)\n0. [**Modifier classes**](#bem)\n\n##### Example\n\n```scss\n.c-example {\n  @include example-mixin();\n  padding: 20px;\n  position: relative;\n  font-size: 1.25em;\n  color: black;\n  border: solid 1px grey;\n  transition: border 1s ease;\n\n  \u0026:focus,\n  \u0026:hover {\n    text-decoration: underline;\n    border: solid 1px black;\n  }\n\n  @media(min-width: 721px) {\n    font-size: 1em;\n  }\n}\n\n.c-example__heading {\n  text-transform: uppercase;\n}\n\n/* States\n  =========================================== */\n\n.c-example.is-active {\n  border: solid 1px blue;\n}\n\n/* Modifiers\n  =========================================== */\n\n.c-example--large {\n  font-size: 2.5em;\n}\n```\n\n[⬆ Back to contents](#contents)\n\n### Extending and Modifying\n\n:warning: **Never** use `@extend`.\n\nExtending styles isn't flexible and leads to bloated stylesheets. When re-building common styles, `@mixin`s are always a more powerful and stable approach.\n\n:warning: **Never** directly overwrite a previously defined class.\n\nAvoid the confusion of selectors being defined in multiple places by using a new [BEM](#bem) `--modifier` class.\n\n```scss\n/* .c-example is a component defined earlier in the project */\n\n/* Don't overwrite the class */\n.c-example {\n  color: red;\n}\n\n/* Do create a new `--modifier` class */\n.c-example--error {\n  color: red;\n}\n```\n\n[⬆ Back to contents](#contents)\n\n### Specificity\n\nBy following the steps above (specifically by using classes and limited nesting) conflicts with specificity shouldn't be a problem.\n\n:warning: **Never** use `!important`\n\nIf you're struggling to override styles, battling specificity, the safest option is to [chain the selector to itself](http://csswizardry.com/2014/07/hacks-for-dealing-with-specificity/#safely-increasing-specificity). In SCSS we can achieve this by:\n\n```scss\n/**\n * Doubling up a selector's specificity in SCSS.\n *\n * 1. Outputs as `.c-example.c-example`\n *\n */\n\n.c-example {\n  color: #4a4a4a;\n\n  \u0026#{\u0026} { /* [1] */\n    text-decoration: none;\n  }\n}\n```\n\n[⬆ Back to contents](#contents)\n\n### Resources\n\n#### Reference\n\n* [CSS Almanac (CSS-Tricks)](https://css-tricks.com/almanac/)\n* [cssreference.io](http://cssreference.io/)\n* [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference)\n\n#### Guides\n\n* [Code Guide](http://codeguide.co/)\n* [CSS Guidelines](http://cssguidelin.es/)\n* [idiomatic-css](https://github.com/necolas/idiomatic-css)\n* [OOCSS](https://www.smashingmagazine.com/2011/12/an-introduction-to-object-oriented-css-oocss/)\n\n#### Organisation Style Guides\n\n* [Airbnb](https://github.com/airbnb/css)\n* [Dropbox](https://github.com/dropbox/css-style-guide)\n* [Primer (GitHub)](http://primercss.io/guidelines/)\n\n[⬆ Back to contents](#contents)\n\n---\n\n## Linter\n\n### Installation\n\nOur CSS linter runs on [Stylelint](https://github.com/stylelint/stylelint), you can install the configuration by running:\n\n```\n$ npm install stylelint-config-sky-uk --save\n```\n\nAfter installing, create/amend your `.stylelintrc` to extend the config:\n\n```\n{\n  \"extends\": \"stylelint-config-sky-uk\"\n}\n```\n\n### Usage\n\nRun the following command to lint all `.scss` files in your project directory.:\n\n```\n$ stylelint '**/*.scss' --syntax scss\n```\n\nTo ignore dependency folders such as `node_modules`, you'll need to create a [`.stylelintignore`](https://github.com/sky-uk/css/blob/master/.stylelintignore) file or use `--ignore-path` in the CLI.\n\n### Versioning\n\nThe CSS Style Guide follows [Semantic Versioning](http://semver.org) to help manage the impact of releasing new library versions.\n\n### Maintainers\n\nThe CSS Style Guide is maintained by the [Toolkit Champions](https://github.com/sky-uk/toolkit#champions).\n","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsky-uk%2Fcss","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsky-uk%2Fcss","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsky-uk%2Fcss/lists"}