Sass

Личный сайт Go-разработчика из Казани

Sass is a CSS extension language that adds features such as variables, nesting, mixins and more. Sass (and other preprocessors, such as Less) help developers write maintainable and DRY (Don’t Repeat Yourself) code.

Sass has two different syntax options to choose from. SCSS, which has the same syntax as CSS but with the added features of Sass. Or Sass (the original syntax), which uses indentation rather than curly braces and semicolons. This tutorial is written using SCSS.

If you’re already familiar with CSS3, you’ll be able to pick up Sass relatively quickly. It does not provide any new styling properties but rather the tools to write your CSS more efficiently and make maintenance much easier.

1//Single line comments are removed when Sass is compiled to CSS. 2 3/* Multi line comments are preserved. */ 4 5 6 7/* Variables 8============================== */ 9 10 11 12/* You can store a CSS value (such as a color) in a variable. 13Use the '$' symbol to create a variable. */ 14 15$primary-color: #A3A4FF; 16$secondary-color: #51527F; 17$body-font: 'Roboto', sans-serif; 18 19/* You can use the variables throughout your stylesheet. 20Now if you want to change a color, you only have to make the change once. */ 21 22body { 23 background-color: $primary-color; 24 color: $secondary-color; 25 font-family: $body-font; 26} 27 28/* This would compile to: */ 29body { 30 background-color: #A3A4FF; 31 color: #51527F; 32 font-family: 'Roboto', sans-serif; 33} 34 35/* This is much more maintainable than having to change the color 36each time it appears throughout your stylesheet. */ 37 38 39 40/* Control Directives 41============================== */ 42 43/* Sass lets you use @if, @else, @for, @while, and @each to control the 44 compilation of your code to CSS. */ 45 46/* @if/@else blocks behave exactly as you might expect */ 47 48$debug: true !default; 49 50@mixin debugmode { 51 @if $debug { 52 @debug "Debug mode enabled"; 53 54 display: inline-block; 55 } 56 @else { 57 display: none; 58 } 59} 60 61.info { 62 @include debugmode; 63} 64 65/* If $debug is set to true, .info is displayed; if it's set to false then 66.info is not displayed. 67 68Note: @debug will output debugging information to the command line. 69Useful for checking variables while debugging your SCSS. */ 70 71.info { 72 display: inline-block; 73} 74 75/* @for is a control loop that iterates through a range of values. 76Particularly useful for setting styles on a collection of items. 77There are two forms, "through" and "to". The former includes the last value, 78the latter stops at the last value. */ 79 80@for $c from 1 to 4 { 81 div:nth-of-type(#{$c}) { 82 left: ($c - 1) * 900 / 3; 83 } 84} 85 86@for $c from 1 through 3 { 87 .myclass-#{$c} { 88 color: rgb($c * 255 / 3, $c * 255 / 3, $c * 255 / 3); 89 } 90} 91 92/* Will compile to: */ 93 94div:nth-of-type(1) { 95 left: 0; 96} 97 98div:nth-of-type(2) { 99 left: 300; 100} 101 102div:nth-of-type(3) { 103 left: 600; 104} 105 106.myclass-1 { 107 color: #555555; 108} 109 110.myclass-2 { 111 color: #aaaaaa; 112} 113 114.myclass-3 { 115 color: white; 116// SASS automatically converts #FFFFFF to white 117} 118 119/* @while is very straightforward: */ 120 121$columns: 4; 122$column-width: 80px; 123 124@while $columns > 0 { 125 .col-#{$columns} { 126 width: $column-width; 127 left: $column-width * ($columns - 1); 128 } 129 130 $columns: $columns - 1; 131} 132 133/* Will output the following CSS: */ 134 135.col-4 { 136 width: 80px; 137 left: 240px; 138} 139 140.col-3 { 141 width: 80px; 142 left: 160px; 143} 144 145.col-2 { 146 width: 80px; 147 left: 80px; 148} 149 150.col-1 { 151 width: 80px; 152 left: 0px; 153} 154 155/* @each functions like @for, except using a list instead of ordinal values 156Note: you specify lists just like other variables, with spaces as 157delimiters. */ 158 159$social-links: facebook twitter linkedin reddit; 160 161.social-links { 162 @each $sm in $social-links { 163 .icon-#{$sm} { 164 background-image: url("images/#{$sm}.png"); 165 } 166 } 167} 168 169/* Which will output: */ 170 171.social-links .icon-facebook { 172 background-image: url("images/facebook.png"); 173} 174 175.social-links .icon-twitter { 176 background-image: url("images/twitter.png"); 177} 178 179.social-links .icon-linkedin { 180 background-image: url("images/linkedin.png"); 181} 182 183.social-links .icon-reddit { 184 background-image: url("images/reddit.png"); 185} 186 187 188/* Mixins 189==============================*/ 190 191/* If you find you are writing the same code for more than one 192element, you might want to store that code in a mixin. 193 194Use the '@mixin' directive, plus a name for your mixin. */ 195 196@mixin center { 197 display: block; 198 margin-left: auto; 199 margin-right: auto; 200 left: 0; 201 right: 0; 202} 203 204/* You can use the mixin with '@include' and the mixin name. */ 205 206div { 207 @include center; 208 background-color: $primary-color; 209} 210 211/* Which would compile to: */ 212div { 213 display: block; 214 margin-left: auto; 215 margin-right: auto; 216 left: 0; 217 right: 0; 218 background-color: #A3A4FF; 219} 220 221/* You can use mixins to create a shorthand property. */ 222 223@mixin size($width, $height) { 224 width: $width; 225 height: $height; 226} 227 228/* Which you can invoke by passing width and height arguments. */ 229 230.rectangle { 231 @include size(100px, 60px); 232} 233 234.square { 235 @include size(40px, 40px); 236} 237 238/* Compiles to: */ 239.rectangle { 240 width: 100px; 241 height: 60px; 242} 243 244.square { 245 width: 40px; 246 height: 40px; 247} 248 249 250 251/* Functions 252============================== */ 253 254 255 256/* Sass provides functions that can be used to accomplish a variety of 257 tasks. Consider the following */ 258 259/* Functions can be invoked by using their name and passing in the 260 required arguments */ 261body { 262 width: round(10.25px); 263} 264 265.footer { 266 background-color: fade_out(#000000, 0.25); 267} 268 269/* Compiles to: */ 270 271body { 272 width: 10px; 273} 274 275.footer { 276 background-color: rgba(0, 0, 0, 0.75); 277} 278 279/* You may also define your own functions. Functions are very similar to 280 mixins. When trying to choose between a function or a mixin, remember 281 that mixins are best for generating CSS while functions are better for 282 logic that might be used throughout your Sass code. The examples in 283 the 'Math Operators' section are ideal candidates for becoming a reusable 284 function. */ 285 286/* This function will take a target size and the parent size and calculate 287 and return the percentage */ 288 289@function calculate-percentage($target-size, $parent-size) { 290 @return $target-size / $parent-size * 100%; 291} 292 293$main-content: calculate-percentage(600px, 960px); 294 295.main-content { 296 width: $main-content; 297} 298 299.sidebar { 300 width: calculate-percentage(300px, 960px); 301} 302 303/* Compiles to: */ 304 305.main-content { 306 width: 62.5%; 307} 308 309.sidebar { 310 width: 31.25%; 311} 312 313 314 315/* Extend (Inheritance) 316============================== */ 317 318 319 320/* Extend is a way to share the properties of one selector with another. */ 321 322.display { 323 @include size(5em, 5em); 324 border: 5px solid $secondary-color; 325} 326 327.display-success { 328 @extend .display; 329 border-color: #22df56; 330} 331 332/* Compiles to: */ 333.display, .display-success { 334 width: 5em; 335 height: 5em; 336 border: 5px solid #51527F; 337} 338 339.display-success { 340 border-color: #22df56; 341} 342 343/* Extending a CSS statement is preferable to creating a mixin 344 because of the way Sass groups together the classes that all share 345 the same base styling. If this was done with a mixin, the width, 346 height, and border would be duplicated for each statement that 347 called the mixin. While it won't affect your workflow, it will 348 add unnecessary bloat to the files created by the Sass compiler. */ 349 350 351 352/* Nesting 353============================== */ 354 355 356 357/* Sass allows you to nest selectors within selectors */ 358 359ul { 360 list-style-type: none; 361 margin-top: 2em; 362 363 li { 364 background-color: #FF0000; 365 } 366} 367 368/* '&' will be replaced by the parent selector. */ 369/* You can also nest pseudo-classes. */ 370/* Keep in mind that over-nesting will make your code less maintainable. 371Best practices recommend going no more than 3 levels deep when nesting. 372For example: */ 373 374ul { 375 list-style-type: none; 376 margin-top: 2em; 377 378 li { 379 background-color: red; 380 381 &:hover { 382 background-color: blue; 383 } 384 385 a { 386 color: white; 387 } 388 } 389} 390 391/* Compiles to: */ 392 393ul { 394 list-style-type: none; 395 margin-top: 2em; 396} 397 398ul li { 399 background-color: red; 400} 401 402ul li:hover { 403 background-color: blue; 404} 405 406ul li a { 407 color: white; 408} 409 410 411 412/* Partials and Imports 413============================== */ 414 415 416 417/* Sass allows you to create partial files. This can help keep your Sass 418 code modularized. Partial files should begin with an '_', e.g. _reset.css. 419 Partials are not generated into CSS. */ 420 421/* Consider the following CSS which we'll put in a file called _reset.css */ 422 423html, 424body, 425ul, 426ol { 427 margin: 0; 428 padding: 0; 429} 430 431/* Sass offers @import which can be used to import partials into a file. 432 This differs from the traditional CSS @import statement which makes 433 another HTTP request to fetch the imported file. Sass takes the 434 imported file and combines it with the compiled code. */ 435 436@import 'reset'; 437 438body { 439 font-size: 16px; 440 font-family: Helvetica, Arial, Sans-serif; 441} 442 443/* Compiles to: */ 444 445html, body, ul, ol { 446 margin: 0; 447 padding: 0; 448} 449 450body { 451 font-size: 16px; 452 font-family: Helvetica, Arial, Sans-serif; 453} 454 455 456 457/* Placeholder Selectors 458============================== */ 459 460 461 462/* Placeholders are useful when creating a CSS statement to extend. If you 463 wanted to create a CSS statement that was exclusively used with @extend, 464 you can do so using a placeholder. Placeholders begin with a '%' instead 465 of '.' or '#'. Placeholders will not appear in the compiled CSS. */ 466 467%content-window { 468 font-size: 14px; 469 padding: 10px; 470 color: #000; 471 border-radius: 4px; 472} 473 474.message-window { 475 @extend %content-window; 476 background-color: #0000ff; 477} 478 479/* Compiles to: */ 480 481.message-window { 482 font-size: 14px; 483 padding: 10px; 484 color: #000; 485 border-radius: 4px; 486} 487 488.message-window { 489 background-color: #0000ff; 490} 491 492 493 494/* Math Operations 495============================== */ 496 497 498 499/* Sass provides the following operators: +, -, *, /, and %. These can 500 be useful for calculating values directly in your Sass files instead 501 of using values that you've already calculated by hand. Below is an example 502 of a setting up a simple two column design. */ 503 504$content-area: 960px; 505$main-content: 600px; 506$sidebar-content: 300px; 507 508$main-size: $main-content / $content-area * 100%; 509$sidebar-size: $sidebar-content / $content-area * 100%; 510$gutter: 100% - ($main-size + $sidebar-size); 511 512body { 513 width: 100%; 514} 515 516.main-content { 517 width: $main-size; 518} 519 520.sidebar { 521 width: $sidebar-size; 522} 523 524.gutter { 525 width: $gutter; 526} 527 528/* Compiles to: */ 529 530body { 531 width: 100%; 532} 533 534.main-content { 535 width: 62.5%; 536} 537 538.sidebar { 539 width: 31.25%; 540} 541 542.gutter { 543 width: 6.25%; 544}

SASS or Sass?

Have you ever wondered whether Sass is an acronym or not? You probably haven’t, but I’ll tell you anyway. The name of the language is a word, «Sass», and not an acronym. Because people were constantly writing it as «SASS», the creator of the language jokingly called it «Syntactically Awesome StyleSheets».

Practice Sass

If you want to play with Sass in your browser, check out SassMeister. You can use either syntax, just go into the settings and select either Sass or SCSS.

Compatibility

Sass can be used in any project as long as you have a program to compile it into CSS. You’ll want to verify that the CSS you’re using is compatible with your target browsers.

QuirksMode CSS and CanIUse are great resources for checking compatibility.

Further reading