├── .version ├── CHANGELOG.md └── README.md /.version: -------------------------------------------------------------------------------- 1 | 2.0.0 -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # HEAD 2 | 3 | ## 2.0.0 (September 11, 2016) 4 | 5 | * General typo and code example fixes. 6 | * Removed all smart quotes. 7 | * Remove all references to the [Scally CSS Framework](https://github.com/chris-pearce/scally) as I want these guidelines to not be tied to any particular framework/library. 8 | * Changed the empty line rule that comes _after_: **Commenting -> Partial Heading** to be one (1) empty line not two (2). 9 | * Removed the non-mandatory sections: `@author` and `@created` from: **Commenting -> Partial Heading** as I don't see any value in this convention anymore. It's better to use source control e.g. [Git](https://git-scm.com/) for this information. 10 | * Removed the **Commenting -> BEM Modifier Markers** section as I don't see any value in this convention anymore. It's obvious a selector is a BEM modifier from the two (2) hyphens in its name e.g. `.c-card--compact`—certainly if a BEM modifier isn't obvious from the code alone then go ahead and add some comments but no need to use the "Modifier" marker convention. 11 | * Removed the **Naming Conventions -> Mixins And Functions** section as it was mostly referring to the [Scally CSS Framework](https://github.com/chris-pearce/scally). 12 | * Removed the **Naming Conventions -> Spelling** section so it's scalable to any team worldwide, basically this should be decided upon by the team. 13 | * A few updates to the **Tooling** section. 14 | * PR's addressed: 15 | * https://github.com/chris-pearce/css-guidelines/pull/17 16 | 17 | ## 1.0.0 (January 7, 2015) 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CSS Guidelines 2 | 3 | 4 | 5 | 6 | ## Contents 7 | 8 | - [Terminology And Conventions Used In These Guidelines](#terminology-and-conventions-used-in-these-guidelines) 9 | - [General Principles](#general-principles) 10 | - [Acknowledgements And Credit](#acknowledgements-and-credit) 11 | - [Syntax And Formatting](#syntax-and-formatting) 12 | - [CSS Ruleset](#css-ruleset) 13 | - [Sass Specifics](#sass-specifics) 14 | - [Declaration Order](#declaration-order) 15 | - [More On Ordering](#more-on-ordering) 16 | - [80 Characters Wide](#80-characters-wide) 17 | - [Meaningful Whitespace](#meaningful-whitespace) 18 | - [Commenting](#commenting) 19 | - [DocBlock-*esque*](#docblock-esque) 20 | - [Partial Heading](#partial-heading) 21 | - [Partial Intro](#partial-intro) 22 | - [Inline Comments](#inline-comments) 23 | - [Number Labelling](#number-labelling) 24 | - [Component-extension Pointers](#component-extension-pointers) 25 | - [Section Comment](#section-comment) 26 | - [Naming Conventions](#naming-conventions) 27 | - [BEM-like Naming](#bem-like-naming) 28 | - [Hyphen-delimited](#hyphen-delimited) 29 | - [Namespace](#namespace) 30 | - [What We Namespace](#what-we-namespace) 31 | - [The Namespaces](#the-namespaces) 32 | - [JS Hooks](#js-hooks) 33 | - [State Hooks](#state-hooks) 34 | - [Server-side Hooks](#server-side-hooks) 35 | - [QA Hooks](#qa-hooks) 36 | - [Tracking Hooks](#tracking-hooks) 37 | - [Settings](#settings) 38 | - [Global Settings](#global-settings) 39 | - [Local Settings](#local-settings) 40 | - [Sizes And Sides](#sizes-and-sides) 41 | - [Tooling](#tooling) 42 | - [Text Editor Configuration](#text-editor-configuration) 43 | - [Sublime Text](#sublime-text) 44 | - [Linting](#linting) 45 | - [EditorConfig](#editorconfig) 46 | - [Writing And Architecturing CSS](#writing-and-architecturing-css) 47 | - [Further Reading](#further-reading) 48 | 49 | 50 | 51 | 52 | ## Terminology And Conventions Used In These Guidelines 53 | 54 | - Sass variable = setting 55 | - An ellipsis (`…`) = a placeholder for code used in a code example block 56 | - Written for a team 57 | 58 | 59 | 60 | 61 | ## General Principles 62 | 63 | > "Part of being a good steward to a successful project is realizing that writing code for yourself is a Bad Idea™. If thousands of people are using your code, then write your code for maximum clarity, not your personal preference of how to get clever within the spec." — [Idan Gazit](http://gazit.me/) 64 | 65 | In working on large, long-running projects, with dozens of developers of differing specialities and abilities, it is important that we all work in a unified way in order to—among other things— 66 | 67 | - keep stylesheets maintainable; 68 | - keep code transparent, sane, consistent, and readable; 69 | - keep stylesheets scalable. 70 | 71 | No matter the document, we must always try and keep a common formatting. This 72 | means: 73 | 74 | - [consistent syntax](#syntax-and-formatting); 75 | - [consistent and meaningful commenting](#commenting); 76 | - and [consistent naming](#naming-conventions). 77 | 78 | All our CSS is written in [Sass](http://sass-lang.com/). Sass provides a lot of incredibly powerful features, however, we don't want to become a platform to showcase Sass' capabilities; we should strive to keep the Sass we write as simple and CSS-like as possible. 79 | 80 | ### Acknowledgements And Credit 81 | 82 | We've borrowed (shamelessly) a lot of our guidelines from [Harry Roberts](http://csswizardry.com/) excellent [CSS Guidelines](http://cssguidelin.es/), and some other sources of inspiration: 83 | 84 | - [Sass Guidelines](http://sass-guidelin.es/) 85 | - [Idiomatic CSS](https://github.com/necolas/idiomatic-css) 86 | 87 | 88 | 89 | 90 | ## Syntax And Formatting 91 | 92 | Starting right at the top, we want 93 | 94 | - four (4) space indents, no tabs; 95 | - [80 character wide](#80-characters-wide) columns; 96 | - multi-line CSS; 97 | - [meaningful use of whitespace](#meaningful-whitespace). 98 | 99 | **N.B.** our [Tooling](#tooling) will automate and enforce most of our syntax and formatting rules. 100 | 101 | ### CSS Ruleset 102 | 103 | For your reference here is an anatomy of a CSS ruleset: 104 | 105 | ``` 106 | [selector] { 107 | [property]: [value]; 108 | [<- Declaration ->] 109 | } 110 | ``` 111 | 112 | Our chosen format for how CSS rulesets should be written 113 | 114 | - each selector on its own new line; 115 | - a space before the opening brace (`{`); 116 | - the opening brace (`{`) on the same line as the last selector; 117 | - a space after the colon (`:`); 118 | - each declaration on its own new line; 119 | - each declaration indented by four (4) spaces; 120 | - a trailing semi-colon (`;`) at the end of all declarations; 121 | - the closing brace (`}`) on its own new line; 122 | - long, comma-separated property values—such as collections of gradients or shadows—arranged across multiple new lines, making sure all values are indented at the same level as the first; 123 | 124 | ###### :heavy_multiplication_x: NOT GOOD 125 | 126 | ```scss 127 | // Not having each selector on its own line 128 | .selector-1, .selector-2 129 | // Not having the opening brace (`{`) on the same line as the last selector 130 | { 131 | // Not having each declaration on its own line 132 | background-color: $color-brand; background-image: linear-gradient($color-white, $color-grey-mercury), linear-gradient($color-black, $color-grey-alabaster); 133 | // Not using new lines for the comma-separated property values and not 134 | // indenting all the values at the same level as the first 135 | box-shadow: 1px 1px 1px $color-black, 2px 2px 1px 1px $color-grey-mercury inset; 136 | // Not using a space after the colon (`:`) 137 | color:$color-text-base; 138 | // Not indenting a declaration with four (4) spaces 139 | display: block; 140 | // Not using a trailing semi-colon (`;`) at the end of the declaration 141 | // and not having the closing brace (`}`) on its own new line 142 | padding: rem($spacing-base) } 143 | ``` 144 | 145 | ###### :heavy_check_mark: GOOD 146 | 147 | ```scss 148 | .selector-1, 149 | .selector-2 { 150 | background-color: $color-brand; 151 | background-image: linear-gradient($color-white, $color-grey-mercury), 152 | linear-gradient($color-black, $color-grey-alabaster); 153 | box-shadow: 1px 1px 1px $color-black, 154 | 2px 2px 1px 1px $color-grey-mercury inset; 155 | color: $color-text-base; 156 | display: block; 157 | padding: rem($spacing-base); 158 | } 159 | ``` 160 | 161 | Adding to the above, we also want to pay attention to 162 | 163 | - use lowercase and preferably the shorthand version for all hexadecimal units—if you wish to use the longhand version then this is fine; 164 | - use shorthands for properties and property values where it makes sense; where it doesn't make sense is using a shorthand property that makes you declare zero-values, here it is better to be explicit even if it means more lines of CSS; 165 | - use single quotes for strings, `url()` values, etc; 166 | - wrap attribute selector values in double quotes; 167 | - include a space after each comma in comma-separated values; 168 | - parentheses should not be padded with spaces; 169 | - when a decimal mark is needed always include the zero; 170 | - use double colons (`::`) for pseudo elements; 171 | - use relative units—pretty much everything is `rem` based and outside of font sizing `em`s may be used for spacing within a component for scaling based on font size, but this should be checked to see what the current approach is as we want consistency with this; 172 | - use the `px` unit for fixed-sized things—this is rare nowadays as we're building responsive layouts—and for the following CSS properties: 173 | - `border-radius` 174 | - `border` 175 | - `box-shadow` 176 | - `text-shadow` 177 | 178 | ###### :heavy_multiplication_x: NOT GOOD 179 | 180 | ```scss 181 | .selector { 182 | // Not using single quotes around the `url()` value 183 | background-image: url(/path/to/image); 184 | // Not using lowercase for the hexidecimal unit 185 | color: #EEEEEE; 186 | // Not using spaces after each comma in the `rgba` value and padding the 187 | // parentheses with spaces 188 | color: rgba( 0,0,0,0.8 ); 189 | // Not including a zero before the decimal mark 190 | font-size: .98rem; 191 | // Not using shorthand for the property value 192 | padding: rem(12) rem(12) rem(12) rem(12); 193 | // Declaring zero-values due to shorthand property being used and not 194 | // removing the unit from a zero-value 195 | margin: 0rem rem(6); 196 | 197 | // Not using the double colon format 198 | &:before { 199 | // Not using shorthand for the property (should be `background-color`) 200 | background: $color-black; 201 | // Not using single quotes around the `content` string 202 | content: "✌"; 203 | } 204 | 205 | // Not using double quotes around the attribute selector value 206 | &[type=text] { 207 | … 208 | } 209 | } 210 | ``` 211 | 212 | ###### :heavy_check_mark: GOOD 213 | 214 | ```scss 215 | .selector-1 { 216 | background-image: url('/path/to/image'); 217 | color: #eee; 218 | color: rgba(0, 0, 0, 0.8); 219 | font-size: 0.98rem; 220 | padding: rem(12); 221 | margin-left: rem(6); 222 | margin-right: rem(6); 223 | 224 | &::before { 225 | background-color: $color-black; 226 | content: '✌'; 227 | } 228 | 229 | &[type="text"] { 230 | … 231 | } 232 | } 233 | ``` 234 | 235 | To expand on this rule: *use shorthands for properties and property values where it makes sense*, treating your properties this way makes for more maintainable and robust CSS. 236 | 237 | A good example of this is using the shorthand `background-color` property instead of the longhand `background` property when you only need to declare a colour. Using the shorthand `background-color` property means we now don't have to worry about potentially having to override all of the properties that come bundled with the longhand `background` property, which are: 238 | 239 | ```scss 240 | background-image: initial; 241 | background-position-x: initial; 242 | background-position-y: initial; 243 | background-size: initial; 244 | background-repeat-x: initial; 245 | background-repeat-y: initial; 246 | background-attachment: initial; 247 | background-origin: initial; 248 | background-clip: initial; 249 | background-color: transparent; 250 | ``` 251 | 252 | *Phew!* 253 | 254 | ### Sass Specifics 255 | 256 | Syntax and formatting rules specifically for Sass code 257 | 258 | - only use the parent selector reference (`&`) for these use cases 259 | - appending it to pseudo classes; 260 | - appending it to pseudo elements; 261 | - appending it to [State hooks](#state-hooks) in order to chain it to the selector it's referencing; 262 | - referencing itself when combined with any of the above to avoid duplicating CSS properties; 263 | - only use silent placeholder selectors with the `@extend` directive, however, we'd rather avoid `@extend` as much as possible; 264 | - avoid selector nesting, if you have to nest then limit it to one level deep; 265 | - when adding a unit to a number stored in a setting, you have to multiply the number by 1 unit; 266 | - hexadecimal units should not exist outside of global and local partial settings i.e. all colours need to be stored in a setting using a meaningful name; 267 | - always use colour settings for `rgb` values; 268 | - avoid writing parentheses for argument-less mixins; 269 | - all Sass functions and mixins to use the [SassDoc](http://sassdoc.com/) documentation guidelines; 270 | - for conditional statements: 271 | - no parentheses unless they are necessary; 272 | - always an empty new line before `@if`; 273 | - `@else` statements on the same line as previous closing brace (`}`); 274 | - always an empty new line after the last closing brace (`}`) unless the next line is a closing brace (`}`); 275 | 276 | ###### :heavy_multiplication_x: NOT GOOD 277 | 278 | ```scss 279 | .selector { 280 | // Extending a class selector 281 | @extend .selector; 282 | // Including parentheses for an argument-less mixin 283 | @include h-text-truncate(); 284 | // Not using colour settings 285 | background-color: rgba(0, 0, 0, 0.5); 286 | color: #eee; 287 | // Not multiplying the unit to a number stored in a setting 288 | padding: $padding-setting + rem; 289 | 290 | // Using the parent selector (`&`) to chain to the selector it's 291 | // referencing when it is not a State hook 292 | &.selector--modifier { 293 | … 294 | } 295 | 296 | // Using the parent selector (`&`) to target a class that is applied at a 297 | // higher level in the DOM 298 | .parent-selector & { 299 | … 300 | } 301 | 302 | // Nesting selectors more than one level deep 303 | .nested__selector .nested__selector { 304 | … 305 | } 306 | } 307 | 308 | // An incorrectly formatted conditional statement 309 | @if ($support-legacy == true) { 310 | … 311 | } 312 | @else { 313 | … 314 | } 315 | 316 | // Not using SassDoc documentation guidelines 317 | @function strip-unit($number) { 318 | @if type-of($number) == "number" and not unitless($number) { 319 | @return $number / ($number * 0 + 1); 320 | } 321 | @return $number; 322 | } 323 | ``` 324 | 325 | ###### :heavy_check_mark: GOOD 326 | 327 | ```scss 328 | .selector { 329 | @extend %selector; 330 | @include h-text-truncate; 331 | background-color: rgba($color-black, 0.5); 332 | color: $color-text-base; 333 | padding: $padding-setting * 1rem; 334 | } 335 | 336 | .selector--modifier { 337 | … 338 | } 339 | 340 | .parent-selector .selector { 341 | … 342 | } 343 | 344 | .nested__selector { 345 | … 346 | } 347 | 348 | @if $support-legacy { 349 | … 350 | } @else { 351 | … 352 | } 353 | 354 | /// Remove a unit from a number. 355 | /// 356 | /// @author Chris Pearce 357 | /// 358 | /// @access private 359 | /// 360 | /// @param {Number [unit]} $number — Number to remove unit from 361 | /// 362 | /// @returns {Number} 363 | /// 364 | /// @todo Add @exception rules, see: https://gist.github.com/terkel/4373420 365 | /// 366 | /// @example scss - Usage 367 | /// strip-unit(24px) 368 | /// strip-unit(2.3em) 369 | 370 | @function strip-unit($number) { 371 | @if type-of($number) == "number" and not unitless($number) { 372 | @return $number / ($number * 0 + 1); 373 | } 374 | @return $number; 375 | } 376 | 377 | // Correct use of the parent selector reference (`&`) 378 | .selector { 379 | … 380 | 381 | &, 382 | &:hover, 383 | &:focus { 384 | color: $color-text-base; 385 | } 386 | 387 | &:hover, 388 | &:focus { 389 | … 390 | } 391 | 392 | &::before { 393 | … 394 | } 395 | 396 | &.is-active { 397 | … 398 | } 399 | } 400 | ``` 401 | 402 | ### Declaration Order 403 | 404 | Properties should be ordered alphabetically, that's it. 405 | 406 | ###### :heavy_multiplication_x: NOT GOOD 407 | 408 | ```scss 409 | .selector { 410 | display: inline-block; 411 | padding-right: rem(10); 412 | padding-left: rem(10); 413 | position: absolute; 414 | top: 0; 415 | bottom: 0; 416 | left: 0; 417 | right: 0; 418 | z-index: 10; 419 | } 420 | ``` 421 | 422 | ###### :heavy_check_mark: GOOD 423 | 424 | ```scss 425 | .selector { 426 | bottom: 0; 427 | display: inline-block; 428 | left: 0; 429 | padding-left: rem(10); 430 | padding-right: rem(10); 431 | position: absolute; 432 | right: 0; 433 | top: 0; 434 | z-index: 10; 435 | } 436 | ``` 437 | 438 | ### More On Ordering 439 | 440 | Because we use Sass we can have more than just declarations between the opening and closing braces (`{ }`) of a ruleset therefore we want to follow a specific order, which is 441 | 442 | 1. extend calls (`@extend`); 443 | 2. mixin calls (`@include`) *with no* `@content`; 444 | 3. declarations; 445 | 4. pseudo classes—combining [State hooks](#state-hooks) here is fine; 446 | 5. pseudo elements; 447 | 5. mixin calls (`@include`) *with* `@content`—mainly being media queries; 448 | 6. nested selectors, limit to one level deep or best to avoid in most cases; 449 | 450 | ###### :heavy_multiplication_x: NOT GOOD 451 | 452 | ```scss 453 | .selector { 454 | // Declarations should not come first and should all be grouped together 455 | bottom: 0; 456 | display: inline-block; 457 | left: 0; 458 | position: absolute; 459 | right: 0; 460 | // Mixin calls should come after extend calls and not mixed in with 461 | // declarations 462 | @include hidpi-bg-img('path/to/image/image.png', 32px); 463 | top: 0; 464 | z-index: 10; 465 | // Extend calls should come first 466 | @extend %some-silent-placeholder-selector; 467 | 468 | // Pseudo elements should not come before pseudo classes 469 | &::before { 470 | … 471 | } 472 | 473 | &:hover, 474 | &:focus, 475 | &.is-active { 476 | … 477 | } 478 | 479 | // Nested selector should come last 480 | .nested-selector { 481 | … 482 | } 483 | 484 | @media (min-width: bp(lap)) { 485 | … 486 | } 487 | } 488 | ``` 489 | 490 | ###### :heavy_check_mark: GOOD 491 | 492 | ```scss 493 | .selector { 494 | @extend %some-silent-placeholder-selector; 495 | @include hidpi-bg-img('path/to/image/image.png', 32px); 496 | bottom: 0; 497 | display: inline-block; 498 | left: 0; 499 | position: absolute; 500 | right: 0; 501 | top: 0; 502 | z-index: 10; 503 | 504 | &:hover, 505 | &:focus, 506 | &.is-active { 507 | … 508 | } 509 | 510 | &::before { 511 | … 512 | } 513 | 514 | @media (min-width: bp(lap)) { 515 | … 516 | } 517 | 518 | .nested-selector { 519 | … 520 | } 521 | } 522 | ``` 523 | 524 | ### 80 Characters Wide 525 | 526 | Where possible, limit CSS files' width to 80 characters. Reasons for this include 527 | 528 | - the ability to have multiple files open side by side; 529 | - viewing CSS on sites like GitHub, or in terminal windows; 530 | - providing a comfortable line length for comments. 531 | 532 | There will be unavoidable exceptions to this rule—such as URLs, or gradient syntax—which shouldn't be worried about. 533 | 534 | ### Meaningful Whitespace 535 | 536 | Whitespace is free, use it liberally and judiciously as it greatly improves the readability of our CSS. 537 | 538 | We want our rulesets, the [discrete sections within our rulesets](#more-on-ordering) and the discrete sections within our partials, to *always* have at least one (1) empty line between them—two (2) empty lines is also fine but never more than two (2). One (1) empty line should *always* be between setting declarations, partial import directives, and a [DocBlock-*esque*](#docblock-esque) style comment and its subject. 539 | 540 | Four (4) empty lines are needed between entirely new sections (see [Section Comment](#section-comment)) however this will hardly ever be needed as we use highly concentrated partials—the most common application for this is within a global master stylesheet. 541 | 542 | ###### :heavy_multiplication_x: NOT GOOD 543 | 544 | ```scss 545 | /* ============================================================================ 546 | COMPONENTS -> SEARCH INPUT 547 | ========================================================================= */ 548 | /** 549 | * A component for the most common type of search input which has deep rounded 550 | * corners, shadows, and a background image of a magnifying glass icon 551 | * positioned to the left or right side. Visit: /subscribers/ to see an 552 | * example. 553 | * @markup 554 |
559 | */ 560 | 561 | /** 562 | * Settings. 563 | */ 564 | 565 | $c-search-input-padding-top: 5; 566 | $c-search-input-padding-bottom: $c-search-input-padding-top + 1; 567 | 568 | .c-search-input { 569 | position: relative; 570 | } 571 | 572 | 573 | 574 | 575 | /** 576 | * The input. 577 | */ 578 | .c-search-input__input { 579 | border: 1px solid $color-grey-alto-4; 580 | box-shadow: $input-box-shadow; 581 | color: $color-grey-tundora; 582 | padding: rem($c-search-input-padding-top); 583 | padding-bottom: rem($c-search-input-padding-bottom); 584 | transition: $input-transition; 585 | &:focus { 586 | border-color: $color-blue-pigeon-post; 587 | box-shadow: $input-box-shadow-focus; 588 | // Can remove this as we're providing a good custom outline 589 | outline: none; 590 | } 591 | } 592 | /** 593 | * The magnify icon. 594 | */ 595 | 596 | .c-search-input__icon { 597 | background: url('/img/icons/icon-small/search.png') no-repeat; 598 | height: $c-search-input-icon-size; 599 | left: $c-search-input-icon-position-left; 600 | width: $c-search-input-icon-size; 601 | } 602 | /** 603 | * Modifier: when icon is positioned on the right side. 604 | */ 605 | .c-search-input--icon-right .c-search-input__icon { 606 | left: auto; 607 | right: $c-search-input-icon-position-left; 608 | } 609 | ``` 610 | 611 | ###### :heavy_check_mark: GOOD 612 | 613 | ```scss 614 | /* ============================================================================ 615 | COMPONENTS -> SEARCH INPUT 616 | ========================================================================= */ 617 | 618 | /** 619 | * A component for the most common type of search input which has deep rounded 620 | * corners, shadows, and a background image of a magnifying glass icon 621 | * positioned to the left or right side. Visit: /subscribers/ to see an 622 | * example. 623 | * 624 | * @markup 625 | 630 | */ 631 | 632 | 633 | /** 634 | * Settings. 635 | */ 636 | 637 | $c-search-input-padding-top: 5; 638 | 639 | $c-search-input-padding-bottom: $c-search-input-padding-top + 1; 640 | 641 | 642 | .c-search-input { 643 | position: relative; 644 | } 645 | 646 | 647 | /** 648 | * The input. 649 | */ 650 | 651 | .c-search-input__input { 652 | border: 1px solid $color-grey-alto-4; 653 | box-shadow: $input-box-shadow; 654 | color: $color-grey-tundora; 655 | padding: rem($c-search-input-padding-top); 656 | padding-bottom: rem($c-search-input-padding-bottom); 657 | transition: $input-transition; 658 | 659 | &:focus { 660 | border-color: $color-blue-pigeon-post; 661 | box-shadow: $input-box-shadow-focus; 662 | // Can remove this as we're providing a good custom outline 663 | outline: none; 664 | } 665 | } 666 | 667 | 668 | /** 669 | * The magnify icon. 670 | */ 671 | 672 | .c-search-input__icon { 673 | background: url('/img/icons/icon-small/search.png') no-repeat; 674 | height: $c-search-input-icon-size; 675 | left: $c-search-input-icon-position-left; 676 | width: $c-search-input-icon-size; 677 | } 678 | 679 | 680 | /** 681 | * Modifier: when icon is positioned on the right side. 682 | */ 683 | 684 | .c-search-input--icon-right .c-search-input__icon { 685 | left: auto; 686 | right: $c-search-input-icon-position-left; 687 | } 688 | ``` 689 | 690 | 691 | 692 | 693 | ## Commenting 694 | 695 | Well commented code is *extremely* important and we really need to be heavily commenting our CSS. Take time to describe components, how they work, their limitations, and the way they are constructed. We don't want to leave others in the team guessing as to the purpose of uncommon or non-obvious code. 696 | 697 | We want to be using a comment style that is simple and consistent. 698 | 699 | Starting right at the top, we want 700 | 701 | - to place comments on a new line above their subject; 702 | - to keep line-length to a sensible maximum: [80 columns](#80-characters-wide); 703 | - to make liberal use of comments to break CSS code into discrete sections; 704 | - to use 'sentence case' comments and consistent text indentation. 705 | 706 | ### DocBlock-*esque* 707 | 708 | The default style of comment we use is a [DocBlock](http://en.wikipedia.org/wiki/PHPDoc#DocBlock)*-esque* style comment. This type of comment begins with `/**` and ends with `*/` and has an `*` at the beginning of every line except when referencing code—the absence of the `*` is so that the code can easily be copied. 709 | 710 | ###### :heavy_check_mark: GOOD 711 | 712 | ```scss 713 | /** 714 | * A component for the most common type of search input which has deep rounded 715 | * corners, shadows, and a background image of a magnifying glass icon 716 | * positioned to the left or right side. Visit: /subscribers/ to see an 717 | * example. 718 | * 719 | * @markup 720 | 725 | */ 726 | ``` 727 | 728 | We should be commenting each discrete piece of CSS in a partial and it should start with a DocBlock*-esque* style comment. One (1) or two (2) empty lines are always used between each discrete piece and one (1) empty line used between the comment and its subject. 729 | 730 | ###### :heavy_check_mark: GOOD 731 | 732 | ```scss 733 | /** 734 | * The underlay which is the wrapper of the modal dialog which uses Flexbox 735 | * to position the modal dialog smack in the middle of the viewport, 736 | * includes a fall-back for non-supporting Flexbox browsers. 737 | */ 738 | 739 | .c-modal-dialog-underlay { 740 | … 741 | } 742 | 743 | /** 744 | * Fall-back for non-supporting Flexbox browsers, using the Modernizr 745 | * feature detection technique via the `:not` CSS selector to get around 746 | * any lag of the Modernizr JS loading. 747 | */ 748 | 749 | html:not(.flexbox) .c-modal-dialog-underlay { 750 | … 751 | } 752 | ``` 753 | 754 | ### Partial Heading 755 | 756 | Every partial needs a partial heading type comment at the very top of the file. 757 | 758 | ###### :heavy_check_mark: GOOD 759 | 760 | ```scss 761 | /* ============================================================================ 762 | CORE -> MIXINS -> CONVERT PX TO EM/REM 763 | ========================================================================= */ 764 | // [empty line] 765 | ``` 766 | 767 | Breaking this down we have 768 | 769 | - uppercase for text; 770 | - a breadcrumb pattern showing where the partial belongs in the CSS architecture, the last part being the same name as the partial filename; 771 | - one (1) empty line to come after. 772 | 773 | ### Partial Intro 774 | 775 | A partial intro type comment follows a [Partial Heading](#partial-heading) type comment, think of this like a books Prologue/Preface/Introduction. 776 | 777 | It should be structured like this 778 | 779 | - a description—be as detailed as you can here; 780 | - any attention grabbing comments prefix with **N.B.**; 781 | - mandatory sections prefixed with `@` 782 | - `@markup`: if applicable the markup that the CSS applies too—this is typically for components—*this should always come last* if you have a living style guide this will no longer be required; 783 | - `@demo`: if applicable any URL(s) to demonstration(s); 784 | - `@credit`: if applicable any URL(s) to credit where any ideas came from; 785 | - non-mandatory sections prefixed with `@` 786 | - `@todo`: any outstanding tasks; 787 | - `@consideration`: any things to consider; 788 | - One (1) empty line between each of the above sections and two (2) empty lines coming after the intro. 789 | 790 | ###### :heavy_check_mark: GOOD 791 | 792 | ```scss 793 | /** 794 | * A generic drop down helper powered by some JavaScript which toggles a 795 | * class e.g. `is-visible` on the drop down trigger (the button that makes the 796 | * drop down visible and invisible) and the target (the actual drop down). 797 | * This class will be used to make the drop down target visible when the 798 | * trigger is selected. There is also a version for showing the drop down via 799 | * the `:hover` pseudo class which is turned off for touch devices. 800 | * 801 | * N.B. this helper is dependent on the "Align" helper. 802 | * 803 | * @credit 804 | * http://www.stubbornella.org/content/2010/06/25/the-media-object-saves-hundreds-of-lines-of-code 805 | * 806 | * @markup 807 |