Sass

Conceitos e sintaxe da linguagem Sass
Voltar
Sass Oficial

O que é Sass?

Sass (Syntactically Awesome Style Sheets) é uma sintaxe extendida e convertida para CSS, nos quais estão presentes a adição de algumas funções bem interessantes às folhas de estilo, deixando-as mais logicamente dinâmicas: Como o próprio site oficial diz "CSS com superpoderes". O Sass possui 2 sintaxes, sendo a '.sass', na qual estão ausentes o uso de chaves e ponto-e-vírgula, sendo os blocos descritos somente por identação. Há também a sintaxe aderida como oficial, a '.scss'(usaremos aqui), na qual estão presentes as chaves e ponto-e-vírgula nos blocos, como em um CSS comum. Os arquivos sass possuem extensão '.scss', independente de seu tipo de sintaxe. O site oficial do Sass encontra-se abaixo, com exemplos, passos para instalação e documentação da linguagem. Arquivos Sass parciais que contêm pequenos trechos de CSS podem ser incluídos em outros arquivos Sass. O nome do arquivo deve ser _nomearquivo.scss. O underline informa ao Sass que o arquivo é parcial e que não deve ser gerado em um arquivo CSS.



Sintaxe


===== SINTAXE SCSS =====
@mixin button-base() { @include typography(button); @include ripple-surface; @include ripple-radius-bounded; display: inline-flex; position: relative; height: $button-height; border: none; vertical-align: middle; &:hover { cursor: pointer; } &:disabled { color: $mdc-button-disabled-ink-color; cursor: default; pointer-events: none; } }
===== COMENTÁRIOS =====
// This comment won't be included in the CSS. /* But this comment will, except in compressed mode. */ /* It can also contain interpolation: * 1 + 1 = #{1 + 1} */ /*! This comment will be included even in compressed mode. */ p /* Multi-line comments can be written anywhere * whitespace is allowed. */ .sans { font: Helvetica, // So can single-line commments. sans-serif; }
===== COMENTÁRIOS DE DOCUMENTO =====
/// Computes an exponent. /// /// @param {number} $base /// The number to multiply by itself. /// @param {integer (unitless)} $exponent /// The number of '$base's to multiply together. /// @return {number} '$base' to the power of '$exponent'. @function pow($base, $exponent) { $result: 1; @for $_ from 1 through $exponent { $result: $result * $base; } @return $result; }
===== FUNÇÕES ESPECIAIS =====
=== URL() === $roboto-font-path: "../fonts/roboto"; @font-face { // This is parsed as a normal function call that takes a quoted string. src: url("#{$roboto-font-path}/Roboto-Thin.woff2") format("woff2"); font-family: "Roboto"; font-weight: 100; } @font-face { // This is parsed as a normal function call that takes an arithmetic expression. src: url($roboto-font-path + "/Roboto-Light.woff2") format("woff2"); font-family: "Roboto"; font-weight: 300; } @font-face { // This is parsed as an interpolated special function. src: url(#{$roboto-font-path}/Roboto-Regular.woff2) format("woff2"); font-family: "Roboto"; font-weight: 400; } === CALC(), ELEMENT(), PROGID(), EXPRESSION() === .logo { $width: 800px; width: $width; position: absolute; left: calc(50% - #{$width / 2}); top: 0; } === MIN(), MAX() === $padding: 12px; .post { // Since these max() calls don't use any Sass features other than // interpolation, they're compiled to CSS max() calls. padding-left: max(#{$padding}, env(safe-area-inset-left)); padding-right: max(#{$padding}, env(safe-area-inset-right)); } .sidebar { // Since these refer to a Sass variable without interpolation, they call // Sass's built-in max() function. padding-left: max($padding, 20px); padding-right: max($padding, 20px); }
===== REGRAS DE ESTILO =====
=== NESTING(Aninhamento) === nav { ul { margin: 0; padding: 0; list-style: none; } li { display: inline-block; } a { display: block; padding: 6px 12px; text-decoration: none; } } === SELETOR LIST === .alert, .warning { ul, p { margin-right: 0; margin-left: 0; padding-bottom: 0; } } === SELETOR COMBINATIORS === ul > { li { list-style-type: none; } } h2 { + p { border-top: 1px solid gray; } } p { ~ { span { opacity: 0.8; } } } === INTERPOLAÇÃO === @mixin define-emoji($name, $glyph) { span.emoji-#{$name} { font-family: IconFont; font-variant: normal; font-weight: normal; content: $glyph; } } @include define-emoji("women-holding-hands", "👭");
===== PROPRIEDADES DECLARATIVAS =====
.circle { $size: 100px; width: $size; height: $size; border-radius: $size / 2; } === INTERPOLAÇÃO === @mixin prefix($property, $value, $prefixes) { @each $prefix in $prefixes { -#{$prefix}-#{$property}: $value; } #{$property}: $value; } .gray { @include prefix(filter, grayscale(50%), moz webkit); } === NESTING(Aninhamento) === .enlarge { font-size: 14px; transition: { property: font-size; duration: 4s; delay: 2s; } &:hover { font-size: 36px; } } === DECLARAÇÕES OCULTAS === $rounded-corners: false; .button { border: 1px solid black; border-radius: if($rounded-corners, 5px, null); } === PROPRIEDADES CUSTOMIZÁVEIS === $primary: #81899b; $accent: #302e24; $warn: #dfa612; :root { --primary: #{$primary}; --accent: #{$accent}; --warn: #{$warn}; // Even though this looks like a Sass variable, it's valid CSS so it's not evaluated. --consumed-by-js: $primary; }
===== SELETORES PAIS(&) =====
.alert { // The parent selector can be used to add pseudo-classes to the outer selector. &:hover { font-weight: bold; } // It can also be used to style the outer selector in a certain context, such as a body set to use a right-to-left language. [dir=rtl] & { margin-left: 0; margin-right: 10px; } // You can even use it as an argument to pseudo-class selectors. :not(&) { opacity: 0.8; } } === ADICIONANDO SUFIXOS === .accordion { max-width: 600px; margin: 4rem auto; width: 90%; font-family: "Raleway", sans-serif; background: #f4f4f4; &__copy { display: none; padding: 1rem 1.5rem 2rem 1.5rem; color: gray; line-height: 1.6; font-size: 14px; font-weight: 500; &--open { display: block; } } } === ANINHAMENTO AVANÇADO === @use "sass:selector"; @mixin unify-parent($child) { @at-root #{selector.unify(&, $child)} { @content; } } .wrapper .field { @include unify-parent("input") { /* ... */ } @include unify-parent("select") { /* ... */ } }
===== SELETORES COMPLEMENTARES(%) =====
.alert:hover, %strong-alert { font-weight: bold; } %strong-alert:hover { color: red; } %toolbelt { box-sizing: border-box; border-top: 1px rgba(#000, .12) solid; padding: 16px 0; width: 100%; &:hover { border: 2px rgba(#000, .5) solid; } } .action-buttons { @extend %toolbelt; color: #4285f4; } .reset-buttons { @extend %toolbelt; color: #cddc39; }
===== VARIÁVEIS($) =====
$base-color: #c6538c; $border-dark: rgba($base-color, 0.88); .alert { border: 1px solid $border-dark; } === VALORES PADRÃO === // _library.scss $black: #000 !default; $border-radius: 0.25rem !default; $box-shadow: 0 0.5rem 1rem rgba($black, 0.15) !default; code { border-radius: $border-radius; box-shadow: $box-shadow; } // style.scss @use 'library' with ( $black: #222, $border-radius: 0.1rem ); === VARIÁVEIS CONSTRUTORAS === @use "sass:math" as math; // This assignment will fail. Não podem ser modificadas math.$pi: 0; === ESCOPO === $global-variable: global value; .content { $local-variable: local value; global: $global-variable; local: $local-variable; } .sidebar { global: $global-variable; // This would fail, because $local-variable isn't in scope: // local: $local-variable; } === SOMBREAMENTO === $variable: global value; .content { $variable: local value; value: $variable; } .sidebar { value: $variable; } $variable: first global value; .content { $variable: second global value !global; value: $variable; } .sidebar { value: $variable; } === CONTROLE DE ESCOPO === $dark-theme: true !default; $primary-color: #f8bbd0 !default; $accent-color: #6a1b9a !default; @if $dark-theme { $primary-color: darken($primary-color, 60%); $accent-color: lighten($accent-color, 60%); } .button { background-color: $primary-color; border: 1px solid $accent-color; border-radius: 3px; } === VARIÁVEIS EM FUNÇÕES AVANÇADAS === @use "sass:map"; $theme-colors: ( "success": #28a745, "info": #17a2b8, "warning": #ffc107, ); .alert { // Instead of $theme-color-#{warning} background-color: map.get($theme-colors, "warning"); }
===== INTERPOLAÇÃO(#{}) =====
@mixin corner-icon($name, $top-or-bottom, $left-or-right) { .icon-#{$name} { background-image: url("/icons/#{$name}.svg"); position: absolute; #{$top-or-bottom}: 0; #{$left-or-right}: 0; } } @include corner-icon("mail", top, left); === STRINGS === .example { unquoted: #{"string"}; }
===== REGRAS GERAIS CHAMADORAS =====
= === @USE === // foundation/_code.scss code { padding: .25em; line-height: 0; } // foundation/_lists.scss ul, ol { text-align: left; & & { padding: { bottom: 0; left: 0; } } } // style.scss @use 'foundation/code'; @use 'foundation/lists'; == Carregando Membros == // src/_corners.scss $radius: 3px; @mixin rounded { border-radius: $radius; } // style.scss @use "src/corners"; .button { @include corners.rounded; padding: 5px + corners.$radius; } == Escolhendo um Namespace == // src/_corners.scss $radius: 3px; @mixin rounded { border-radius: $radius; } // style.scss @use "src/corners" as c; .button { @include c.rounded; padding: 5px + c.$radius; } // src/_corners.scss $radius: 3px; @mixin rounded { border-radius: $radius; } // style.scss @use "src/corners" as *; .button { @include rounded; padding: 5px + $radius; } == Membros Privados == // src/_corners.scss $-radius: 3px; @mixin rounded { border-radius: $-radius; } // style.scss @use "src/corners"; .button { @include corners.rounded; // This is an error! $-radius isn't visible outside of '_corners.scss'. padding: 5px + corners.$-radius; } == Configuração == // _library.scss $black: #000 !default; $border-radius: 0.25rem !default; $box-shadow: 0 0.5rem 1rem rgba($black, 0.15) !default; code { border-radius: $border-radius; box-shadow: $box-shadow; } // style.scss @use 'library' with ( $black: #222, $border-radius: 0.1rem ); == Com Mixins == // _library.scss $-black: #000; $-border-radius: 0.25rem; $-box-shadow: null; /// If the user has configured '$-box-shadow', returns their configured value. /// Otherwise returns a value derived from '$-black'. @function -box-shadow() { @return $-box-shadow or (0 0.5rem 1rem rgba($-black, 0.15)); } @mixin configure($black: null, $border-radius: null, $box-shadow: null) { @if $black { $-black: $black !global; } @if $border-radius { $-border-radius: $border-radius !global; } @if $box-shadow { $-box-shadow: $box-shadow !global; } } @mixin styles { code { border-radius: $-border-radius; box-shadow: -box-shadow(); } } // style.scss @use 'library'; @include library.configure( $black: #222, $border-radius: 0.1rem ); @include library.styles; == Pesquisando Módulo, Index == // foundation/_code.scss code { padding: .25em; line-height: 0; } // foundation/_lists.scss ul, ol { text-align: left; & & { padding: { bottom: 0; left: 0; } } } // foundation/_index.scss @use 'code'; @use 'lists'; // style.scss @use 'foundation'; == Carregando Css == // code.css code { padding: .25em; line-height: 0; } // style.scss @use 'code'; === @FOWARD === Encaminha, juntamente com códigos, @uses, @functions, @mixins e $vars // src/_list.scss @mixin list-reset { margin: 0; padding: 0; list-style: none; } // bootstrap.scss @forward "src/list"; // styles.scss @use "bootstrap"; li { @include bootstrap.list-reset; } == Adicionando um Prefixo == // src/_list.scss @mixin reset { margin: 0; padding: 0; list-style: none; } // bootstrap.scss @forward "src/list" as list-*; // styles.scss @use "bootstrap"; li { @include bootstrap.list-reset; } == Controlando Visibilidade === // src/_list.scss $horizontal-list-gap: 2em; @mixin list-reset { margin: 0; padding: 0; list-style: none; } @mixin list-horizontal { @include reset; li { display: inline-block; margin: { left: -2px; right: $horizontal-list-gap; } } } // bootstrap.scss @forward "src/list" hide list-reset, $horizontal-list-gap; == Configurando Módulos == // _library.scss $black: #000 !default; $border-radius: 0.25rem !default; $box-shadow: 0 0.5rem 1rem rgba($black, 0.15) !default; code { border-radius: $border-radius; box-shadow: $box-shadow; } // _opinionated.scss @forward 'library' with ( $black: #222 !default, $border-radius: 0.1rem !default ); // style.scss @use 'opinionated' with ($black: #333); === @IMPORT === Importar arquivo(s) CSS e SASS com funções, vars, uses... // foundation/_code.scss code { padding: .25em; line-height: 0; } // foundation/_lists.scss ul, ol { text-align: left; & & { padding: { bottom: 0; left: 0; } } } // style.scss @import 'foundation/code', 'foundation/lists'; == Arquivo Index == // foundation/_code.scss code { padding: .25em; line-height: 0; } // foundation/_lists.scss ul, ol { text-align: left; & & { padding: { bottom: 0; left: 0; } } } // foundation/_index.scss @import 'code', 'lists'; // style.scss @import 'foundation'; == Aninhamento == // _theme.scss pre, code { font-family: 'Source Code Pro', Helvetica, Arial; border-radius: 4px; } // style.scss .theme-sample { @import "theme"; } == Importar Css == // code.css code { padding: .25em; line-height: 0; } // style.scss @import 'code'; == Planejando Css com @import == @import "theme.css"; @import "http://fonts.googleapis.com/css?family=Droid+Sans"; @import url(theme); @import "landscape" screen and (orientation: landscape); == Interpolação == @mixin google-font($family) { @import url("http://fonts.googleapis.com/css?family=#{$family}"); } @include google-font("Droid Sans"); == Importar e Módulos == // _reset.scss // Module system users write '@include reset.list()'. @mixin list() { ul { margin: 0; padding: 0; list-style: none; } } // _reset.import.scss // Legacy import users can keep writing '@include reset-list()'. @forward "reset" as reset-*; == Configurando Módulos com @import == // _library.scss $color: blue !default; a { color: $color; } // _library.import.scss @forward 'library' as lib-*; // style.sass $lib-color: green; @import "library"; == @MIXIN e @INCLUDE == Definir estilos e reutilizá-los através de CSS @mixin reset-list { margin: 0; padding: 0; list-style: none; } @mixin horizontal-list { @include reset-list; li { display: inline-block; margin: { left: -2px; right: 2em; } } } nav ul { @include horizontal-list; } == Argumentos == @mixin rtl($property, $ltr-value, $rtl-value) { #{$property}: $ltr-value; [dir=rtl] & { #{$property}: $rtl-value; } } .sidebar { @include rtl(float, left, right); } == Argumentos Opcionais == @mixin replace-text($image, $x: 50%, $y: 50%) { text-indent: -99999em; overflow: hidden; text-align: left; background: { image: $image; repeat: no-repeat; position: $x $y; } } .mail-icon { @include replace-text(url("/images/mail.svg"), 0); } == Argumentos de Teclado == @mixin square($size, $radius: 0) { width: $size; height: $size; @if $radius != 0 { border-radius: $radius; } } .avatar { @include square(100px, $radius: 4px); } == Argumentos Arbitrários == @mixin order($height, $selectors...) { @for $i from 0 to length($selectors) { #{nth($selectors, $i + 1)} { position: absolute; height: $height; margin-top: $i * $height; } } } @include order(150px, "input.name", "input.address", "input.zip"); == Argumentos de Teclado Arbitrários == @use "sass:meta"; @mixin syntax-colors($args...) { @debug meta.keywords($args); // (string: #080, comment: #800, variable: #60b) @each $name, $color in meta.keywords($args) { pre span.stx-#{$name} { color: $color; } } } @include syntax-colors( $string: #080, $comment: #800, $variable: #60b, ) == Passando Argumentos Arbitrários == $form-selectors: "input.name", "input.address", "input.zip" !default; @include order(150px, $form-selectors...); == Blocos de Conteúdo == @mixin hover { &:not([disabled]):hover { @content; } } .button { border: 1px solid black; @include hover { border-width: 2px; } } == Passando Argumentos à Blocos de Conteúdo == @mixin media($types...) { @each $type in $types { @media #{$type} { @content($type); } } } @include media(screen, print) using ($type) { h1 { font-size: 40px; @if $type == print { font-family: Calluna; } } } === @FUNCTION === @function pow($base, $exponent) { $result: 1; @for $_ from 1 through $exponent { $result: $result * $base; } @return $result; } .sidebar { float: left; margin-left: pow(4, 3) * 1px; } == Argumentos Opcionais == @function invert($color, $amount: 100%) { $inverse: change-color($color, $hue: hue($color) + 180); @return mix($inverse, $color, $amount); } $primary-color: #036; .header { background-color: invert($primary-color, 80%); } == Argumentos de Teclado == $primary-color: #036; .banner { background-color: $primary-color; color: scale-color($primary-color, $lightness: +40%); } == Obtendo Argumentos Arbitrários == @function sum($numbers...) { $sum: 0; @each $number in $numbers { $sum: $sum + $number; } @return $sum; } .micro { width: sum(50px, 30px, 100px); } == Passando Argumentos Arbitrários == $widths: 50px, 30px, 100px; .micro { width: min($widths...); } == @return == @use "sass:string"; @function str-insert($string, $insert, $index) { // Avoid making new strings if we don't need to. @if string.length($string) == 0 { @return $insert; } $before: string.slice($string, 0, $index); $after: string.slice($string, $index); @return $before + $insert + $after; } == Funções de Pano CSS == @debug var(--main-bg-color); // var(--main-bg-color) $primary: #f2ece4; $accent: #e1d7d2; @debug radial-gradient($primary, $accent); // radial-gradient(#f2ece4, #e1d7d2) === @EXTEND === <div class="error error--serious"> Oh no! You've been hacked! </div> .error { border: 1px #f00; background-color: #fdd; } .error--serious { border-width: 3px; } .error { border: 1px #f00; background-color: #fdd; &--serious { @extend .error; border-width: 3px; } } .error:hover { background-color: #fee; } .error--serious { @extend .error; border-width: 3px; } == Como Trabalhar == .content nav.sidebar { @extend .info; } // This won't be extended, because 'p' is incompatible with 'nav'. p.info { background-color: #dee9fc; } // There's no way to know whether '<div class="guide">' will be inside or outside '<div class="content">', so Sass generates both to be safe. .guide .info { border: 1px solid rgba(#000, 0.8); border-radius: 2px; } // Sass knows that every element matching "main.content" also matches ".content" and avoids generating unnecessary interleaved selectors. main.content .info { font-size: 0.8em; } == Seletores Marcadores == .alert:hover, %strong-alert { font-weight: bold; } %strong-alert:hover { color: red; } == Limitações == .alert { @extend .message.info; // ^^^^^^^^^^^^^ // Error: Write @extend .message, .info instead. @extend .main .info; // ^^^^^^^^^^^ // Error: write @extend .info instead. } == Heurísticas Html == header .warning li { font-weight: bold; } aside .notice dd { // Sass doesn't generate CSS to match the <dd> in // // <header> // <aside> // <div class="warning"> // <div class="notice"> // <dd>...</dd> // </div> // </div> // </aside> // </header> // // because matching all elements like that would require us to generate nine // new selectors instead of just two. @extend li; } == Extendendo em @media == @media screen and (max-width: 600px) { .error--serious { @extend .error; // ^^^^^^ // Error: ".error" was extended in @media, but used outside it. } } .error { border: 1px #f00; background-color: #fdd; } === @ERROR === @mixin reflexive-position($property, $value) { @if $property != left and $property != right { @error "Property #{$property} must be either left or right."; } $left-value: if($property == right, initial, $value); $right-value: if($property == right, $value, initial); left: $left-value; right: $right-value; [dir=rtl] & { left: $right-value; right: $left-value; } } .sidebar { @include reflexive-position(top, 12px); // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // Error: Property top must be either left or right. } (Erro Exibido) Error: "Property top must be either left or right." ╷ 3 │ @error "Property #{$property} must be either left or right."; │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ╵ example.scss 3:5 reflexive-position() example.scss 19:3 root stylesheet === @WARN === $known-prefixes: webkit, moz, ms, o; @mixin prefix($property, $value, $prefixes) { @each $prefix in $prefixes { @if not index($known-prefixes, $prefix) { @warn "Unknown prefix #{$prefix}."; } -#{$prefix}-#{$property}: $value; } #{$property}: $value; } .tilt { // Oops, we typo'd "webkit" as "wekbit"! @include prefix(transform, rotate(15deg), wekbit ms); } (Warn Exibido) Warning: Unknown prefix wekbit. example.scss 6:7 prefix() example.scss 16:3 root stylesheet === @DEBUG === @mixin inset-divider-offset($offset, $padding) { $divider-offset: (2 * $padding) + $offset; @debug "divider offset: #{$divider-offset}"; margin-left: $divider-offset; width: calc(100% - #{$divider-offset}); } (Debug Exibido) test.scss:3 Debug: divider offset: 132px === @AT-ROOT === @use "sass:selector"; @mixin unify-parent($child) { @at-root #{selector.unify(&, $child)} { @content; } } .wrapper .field { @include unify-parent("input") { /* ... */ } @include unify-parent("select") { /* ... */ } } == Entre Regras de Estilo == @media print { .page { width: 8in; @at-root (without: media) { color: #111; } @at-root (with: rule) { font-size: 1.2em; } } }
===== CONTROLE DE FLUXO =====
=== @IF e @ELSE === (If) @mixin avatar($size, $circle: false) { width: $size; height: $size; @if $circle { border-radius: $size / 2; } } .square-av { @include avatar(100px, $circle: false); } .circle-av { @include avatar(100px, $circle: true); } (Else) $light-background: #f2ece4; $light-text: #036; $dark-background: #6b717f; $dark-text: #d2e1dd; @mixin theme-colors($light-theme: true) { @if $light-theme { background-color: $light-background; color: $light-text; } @else { background-color: $dark-background; color: $dark-text; } } .banner { @include theme-colors($light-theme: true); body.dark & { @include theme-colors($light-theme: false); } } (Else If) @mixin triangle($size, $color, $direction) { height: 0; width: 0; border-color: transparent; border-style: solid; border-width: $size / 2; @if $direction == up { border-bottom-color: $color; } @else if $direction == right { border-left-color: $color; } @else if $direction == down { border-top-color: $color; } @else if $direction == left { border-right-color: $color; } @else { @error "Unknown direction #{$direction}."; } } .next { @include triangle(5px, black, right); } === @EACH(Foreach) === $sizes: 40px, 50px, 80px; @each $size in $sizes { .icon-#{$size} { font-size: $size; height: $size; width: $size; } } == Com Mapas == $icons: ("eye": "\f112", "start": "\f12e", "stop": "\f12f"); @each $name, $glyph in $icons { .icon-#{$name}:before { display: inline-block; font-family: "Icon Font"; content: $glyph; } } == Desestruturando == $icons: "eye" "\f112" 12px, "start" "\f12e" 16px, "stop" "\f12f" 10px; @each $name, $glyph, $size in $icons { .icon-#{$name}:before { display: inline-block; font-family: "Icon Font"; content: $glyph; font-size: $size; } } === @FOR === $base-color: #036; @for $i from 1 through 3 { ul:nth-child(3n + #{$i}) { background-color: lighten($base-color, $i * 5%); } } === @WHILE === /// Divides '$value' by '$ratio' until it's below '$base'. @function scale-below($value, $base, $ratio: 1.618) { @while $value > $base { $value: $value / $ratio; } @return $value; } $normal-font-size: 16px; sup { font-size: scale-below(20px, 16px); }
===== REGRAS CSS =====
@namespace svg url(http://www.w3.org/2000/svg); @font-face { font-family: "Open Sans"; src: url("/fonts/OpenSans-Regular-webfont.woff2") format("woff2"); } @counter-style thumbs { system: cyclic; symbols: "\1F44D"; } .print-only { display: none; @media print { display: block; } } === @MEDIA === $layout-breakpoint-small: 960px; @media (min-width: $layout-breakpoint-small) { .hide-extra-small { display: none; } } @media (hover: hover) { .button:hover { border: 2px solid black; @media (color) { border-color: #036; } } } === @SUPPORTS === @mixin sticky-position { position: fixed; @supports (position: sticky) { position: sticky; } } .banner { @include sticky-position; } === @KEYFRAMES === @keyframes slide-in { from { margin-left: 100%; width: 300%; } 70% { margin-left: 90%; width: 150%; } to { margin-left: 0%; width: 100%; } }
===== VALORES =====
==== NUMBERS ==== @debug 100; // 100 @debug 0.8; // 0.8 @debug 16px; // 16px @debug 5px * 2px; // 10px*px (read "square pixels") @debug 5.2e3; // 5200 @debug 6e-2; // 0.06 === Unidades === @debug 4px * 6px; // 24px*px (read "square pixels") @debug 5px / 2s; // 2.5px/s (read "pixels per second") @debug 5px * 30deg / 2s / 24em; // 3.125px*deg/s*em // (read "pixel-degrees per second-em") $degrees-per-second: 20deg/1s; @debug $degrees-per-second; // 20deg/s @debug 1 / $degrees-per-second; // 0.05s/deg // CSS defines one inch as 96 pixels. @debug 1in + 6px; // 102px or 1.0625in @debug 1in + 1s; // ^^^^^^^^ // Error: Incompatible units s and in. $transition-speed: 1s/50px; @mixin move($left-start, $left-stop) { position: absolute; left: $left-start; transition: left ($left-stop - $left-start) * $transition-speed; &:hover { left: $left-stop; } } .slider { @include move(10px, 120px); } === Precisão === @debug 0.012345678912345; // 0.0123456789 @debug 0.01234567891 == 0.01234567899; // true @debug 1.00000000009; // 1 @debug 0.99999999991; // 1 ==== STRINGS ==== @use "sass:string"; @debug string.unquote(".widget:hover"); // .widget:hover @debug string.quote(bold); // "bold" === Escape === @debug "\""; // '"' @debug \.widget; // \.widget @debug "\a"; // "\a" (a string containing only a newline) @debug "line1\a line2"; // "line1\a line2" @debug "Nat + Liz \1F46D"; // "Nat + Liz 👭" === Quoted === @debug "Helvetica Neue"; // "Helvetica Neue" @debug "C:\\Program Files"; // "C:\\Program Files" @debug "\"Don't Fear the Reaper\""; // "\"Don't Fear the Reaper\"" @debug "line1\a line2"; // "line1\a line2" $roboto-variant: "Mono"; @debug "Roboto #{$roboto-variant}"; // "Roboto Mono" === Unquoted === (Ver regras de Unquoted no site oficial) @debug bold; // bold @debug -webkit-flex; // -webkit-flex @debug --123; // --123 $prefix: ms; @debug -#{$prefix}-flex; // -ms-flex === Escapes === @use "sass:string"; @debug \1F46D; // 👭 @debug \21; // \! @debug \7Fx; // \7f x @debug string.length(\7Fx); // 5 === String Indexadas === @use "sass:string"; @debug string.index("Helvetica Neue", "Helvetica"); // 1 @debug string.index("Helvetica Neue", "Neue"); // 11 @debug string.slice("Roboto Mono", -4); // "Mono" ==== COLORS ==== @debug #f2ece4; // #f2ece4 @debug #b37399aa; // rgba(179, 115, 153, 67%) @debug midnightblue; // #191970 @debug rgb(204, 102, 153); // #c69 @debug rgba(107, 113, 127, 0.8); // rgba(107, 113, 127, 0.8) @debug hsl(228, 7%, 86%); // #dadbdf @debug hsla(20, 20%, 85%, 0.7); // rgb(225, 215, 210, 0.7) $venus: #998099; @debug scale-color($venus, $lightness: +15%); // #a893a8 @debug mix($venus, midnightblue); // #594d85 ==== LISTS ==== === Acessando Elemento === @debug list.nth(10px 12px 16px, 2); // 12px @debug list.nth([line1, line2, line3], -1); // line3 === Percorrendo === $sizes: 40px, 50px, 80px; @each $size in $sizes { .icon-#{$size} { font-size: $size; height: $size; width: $size; } } === Adicionando Elemento === @debug append(10px 12px 16px, 25px); // 10px 12px 16px 25px @debug append([col1-line1], col1-line2); // [col1-line1, col1-line2] === Procurando Elemento === @debug list.index(1px solid red, 1px); // 1 @debug list.index(1px solid red, solid); // 2 @debug list.index(1px solid red, dashed); // null @use "sass:list"; $valid-sides: top, bottom, left, right; @mixin attach($side) { @if not list.index($valid-sides, $side) { @error "#{$side} is not a valid side. Expected one of #{$valid-sides}."; } // ... } === Imutabilidade === @use "sass:list"; @use "sass:map"; $prefixes-by-browser: ("firefox": moz, "safari": webkit, "ie": ms); @function prefixes-for-browsers($browsers) { $prefixes: (); @each $browser in $browsers { $prefixes: list.append($prefixes, map.get($prefixes-by-browser, $browser)); } @return $prefixes; } @debug prefixes-for-browsers("firefox" "ie"); // moz ms === Lists de Argumentos === @use "sass:meta"; @mixin syntax-colors($args...) { @debug meta.keywords($args); // (string: #080, comment: #800, variable: #60b) @each $name, $color in meta.keywords($args) { pre span.stx-#{$name} { color: $color; } } } @include syntax-colors( $string: #080, $comment: #800, $variable: #60b, ) ==== MAPS ==== === Usando Maps === $font-weights: ("regular": 400, "medium": 500, "bold": 700); @debug map.get($font-weights, "medium"); // 500 @debug map.get($font-weights, "extra-bold"); // null === Percorrendo Maps === $icons: ("eye": "\f112", "start": "\f12e", "stop": "\f12f"); @each $name, $glyph in $icons { .icon-#{$name}:before { display: inline-block; font-family: "Icon Font"; content: $glyph; } } === Adicionando Elemento === @use "sass:map"; $font-weights: ("regular": 400, "medium": 500, "bold": 700); @debug map.set($font-weights, "extra-bold", 900); // ("regular": 400, "medium": 500, "bold": 700, "extra-bold": 900) @debug map.set($font-weights, "bold", 900); // ("regular": 400, "medium": 500, "bold": 900) @use "sass:map"; $light-weights: ("lightest": 100, "light": 300); $heavy-weights: ("medium": 500, "bold": 700); @debug map.merge($light-weights, $heavy-weights); // ("lightest": 100, "light": 300, "medium": 500, "bold": 700) @use "sass:map"; $weights: ("light": 300, "medium": 500); @debug map.merge($weights, ("medium": 700)); // ("light": 300, "medium": 700) === Imutabilidade === @use "sass:map"; $prefixes-by-browser: ("firefox": moz, "safari": webkit, "ie": ms); @mixin add-browser-prefix($browser, $prefix) { $prefixes-by-browser: map.merge($prefixes-by-browser, ($browser: $prefix)) !global; } @include add-browser-prefix("opera", o); @debug $prefixes-by-browser; // ("firefox": moz, "safari": webkit, "ie": ms, "opera": o) ==== BOOLEAN(True/False) ==== @use "sass:math"; @debug 1px == 2px; // false @debug 1px == 1px; // true @debug 10px < 3px; // false @debug math.comparable(100px, 3in); // true @debug true and true; // true @debug true and false; // false @debug true or false; // true @debug false or false; // false @debug not true; // false @debug not false; // true === Aplicando === @mixin avatar($size, $circle: false) { width: $size; height: $size; @if $circle { border-radius: $size / 2; } } .square-av { @include avatar(100px, $circle: false); } .circle-av { @include avatar(100px, $circle: true); } === Com If === @debug if(true, 10px, 30px); // 10px @debug if(false, 10px, 30px); // 30px ==== NULL ==== @use "sass:map"; @use "sass:string"; @debug string.index("Helvetica Neue", "Roboto"); // null @debug map.get(("large": 20px), "small"); // null @debug &; // null $fonts: ("serif": "Helvetica Neue", "monospace": "Consolas"); h3 { font: 18px bold map-get($fonts, "sans"); } $fonts: ("serif": "Helvetica Neue", "monospace": "Consolas"); h3 { font: { size: 18px; weight: bold; family: map-get($fonts, "sans"); } } @mixin app-background($color) { #{if(&, '&.app-background', '.app-background')} { background-color: $color; color: rgba(#fff, 0.75); } } @include app-background(#036); .sidebar { @include app-background(#c6538c); } ==== FUNCTIONS ==== @use "sass:list"; @use "sass:meta"; @use "sass:string"; /// Return a copy of $list with all elements for which $condition returns 'true' removed. @function remove-where($list, $condition) { $new-list: (); $separator: list.separator($list); @each $element in $list { @if not meta.call($condition, $element) { $new-list: list.append($new-list, $element, $separator: $separator); } } @return $new-list; } $fonts: Tahoma, Geneva, "Helvetica Neue", Helvetica, Arial, sans-serif; content { @function contains-helvetica($string) { @return string.index($string, "Helvetica"); } font-family: remove-where($fonts, meta.get-function("contains-helvetica")); }
===== OPERADORES =====
==== EQUALIDADE ==== @debug 1px == 1px; // true @debug 1px != 1em; // true @debug 1 != 1px; // true @debug 96px == 1in; // true @debug "Helvetica" == Helvetica; // true @debug "Helvetica" != "Arial"; // true @debug hsl(34, 35%, 92.1%) == #f2ece4; // true @debug rgba(179, 115, 153, 0.5) != rgba(179, 115, 153, 0.8); // true @debug (5px 7px 10px) == (5px 7px 10px); // true @debug (5px 7px 10px) != (10px 14px 20px); // true @debug (5px 7px 10px) != (5px, 7px, 10px); // true @debug (5px 7px 10px) != [5px 7px 10px]; // true $theme: ("venus": #998099, "nebula": #d2e1dd); @debug $theme == ("venus": #998099, "nebula": #d2e1dd); // true @debug $theme != ("venus": #998099, "iron": #dadbdf); // true @debug true == true; // true @debug true != false; // true @debug null != false; // true @debug get-function("rgba") == get-function("rgba"); // true @debug get-function("rgba") != get-function("hsla"); // true ==== RELACIONAIS ==== @debug 100 > 50; // true @debug 10px < 17px; // true @debug 96px >= 1in; // true @debug 1000ms <= 1s; // true @debug 100 > 50px; // true @debug 10px < 17; // true @debug 100px > 10s; // ^^^^^^^^^^^ // Error: Incompatible units px and s. ==== NUMÉRICOS ==== @debug 10s + 15s; // 25s @debug 1in - 10px; // 0.8958333333in @debug 5px * 3px; // 15px*px @debug (12px/4px); // 3 @debug 1in % 9px; // 0.0625in @debug 100px + 50; // 150px @debug 4s * 10; // 40s @debug 100px + 10s; // ^^^^^^^^^^^ // Error: Incompatible units px and s. === Operador Unário === @debug +(5s + 7s); // 12s @debug -(50px + 30px); // -80px @debug -(10px - 15px); // 5px === Operações === @debug 15px / 30px; // 15px/30px @debug (10px + 5px) / 30px; // 0.5 @debug #{10px + 5px} / 30px; // 15px/30px $result: 15px / 30px; @debug $result; // 0.5 @function fifteen-divided-by-thirty() { @return 15px / 30px; } @debug fifteen-divided-by-thirty(); // 0.5 @debug (15px/30px); // 0.5 @debug (bold 15px/30px sans-serif); // bold 15px/30px sans-serif @debug 15px/30px + 1; // 1.5 === Unidades === @debug 4px * 6px; // 24px*px (read "square pixels") @debug 5px / 2s; // 2.5px/s (read "pixels per second") @debug 5px * 30deg / 2s / 24em; // 3.125px*deg/s*em // (read "pixel-degrees per second-em") $degrees-per-second: 20deg/1s; @debug $degrees-per-second; // 20deg/s @debug 1 / $degrees-per-second; // 0.05s/deg // CSS defines one inch as 96 pixels. @debug 1in + 6px; // 102px or 1.0625in @debug 1in + 1s; // ^^^^^^^^ // Error: Incompatible units s and in. $transition-speed: 1s/50px; @mixin move($left-start, $left-stop) { position: absolute; left: $left-start; transition: left ($left-stop - $left-start) * $transition-speed; &:hover { left: $left-stop; } } .slider { @include move(10px, 120px); } ==== STRINGS ==== @debug "Helvetica" + " Neue"; // "Helvetica Neue" @debug sans- + serif; // sans-serif @debug #{10px + 5px} / 30px; // 15px/30px @debug sans - serif; // sans-serif @debug "Elapsed time: " + 10s; // "Elapsed time: 10s"; @debug true + " is a boolean value"; // "true is a boolean value"; === Operador Unário === @debug / 15px; // /15px @debug - moz; // -moz ==== BOOLEAN ==== @debug not true; // false @debug not false; // true @debug true and true; // true @debug true and false; // false @debug true or false; // true @debug false or false; // false
===== MÓDULOS CONSTRUTORES =====
==== SASS:COLOR ==== color.adjust($color, $red: null, $green: null, $blue: null, $hue: null, $saturation: null, $lightness: null, $whiteness: null, $blackness: null, $alpha: null) adjust-color(...) //=> color @debug color.adjust(#6b717f, $red: 15); // #7a717f @debug color.adjust(#d2e1dd, $red: -10, $blue: 10); // #c8e1e7 @debug color.adjust(#998099, $lightness: -30%, $alpha: -0.4); // rgba(71, 57, 71, 0.6) adjust-hue($color, $degrees) //=> color // Hue 222deg becomes 282deg. @debug adjust-hue(#6b717f, 60deg); // #796b7f // Hue 164deg becomes 104deg. @debug adjust-hue(#d2e1dd, -60deg); // #d6e1d2 // Hue 210deg becomes 255deg. @debug adjust-hue(#036, 45); // #1a0066 color.alpha($color) alpha($color) opacity($color) //=> number @debug color.alpha(#e1d7d2); // 1 @debug color.opacity(rgb(210, 225, 221, 0.4)); // 0.4 @debug alpha(opacity=20); // alpha(opacity=20) color.blackness($color) //=> number @debug color.blackness(#e1d7d2); // 11.7647058824% @debug color.blackness(white); // 0% @debug color.blackness(black); // 100% color.blue($color) blue($color) //=> number @debug color.blue(#e1d7d2); // 210 @debug color.blue(white); // 255 @debug color.blue(black); // 0 color.change($color, $red: null, $green: null, $blue: null, $hue: null, $saturation: null, $lightness: null, $whiteness: null, $blackness: null, $alpha: null) change-color(...) //=> color @debug color.change(#6b717f, $red: 100); // #64717f @debug color.change(#d2e1dd, $red: 100, $blue: 50); // #64e132 @debug color.change(#998099, $lightness: 30%, $alpha: 0.5); // rgba(85, 68, 85, 0.5) color.complement($color) complement($color) //=> color // Hue 222deg becomes 42deg. @debug color.complement(#6b717f); // #7f796b // Hue 164deg becomes 344deg. @debug color.complement(#d2e1dd); // #e1d2d6 // Hue 210deg becomes 30deg. @debug color.complement(#036); // #663300 darken($color, $amount) //=> color // Lightness 92% becomes 72%. @debug darken(#b37399, 20%); // #7c4465 // Lightness 85% becomes 45%. @debug darken(#f2ece4, 40%); // #b08b5a // Lightness 20% becomes 0%. @debug darken(#036, 30%); // black desaturate($color, $amount) //=> color // Saturation 100% becomes 80%. @debug desaturate(#036, 20%); // #0a335c // Saturation 35% becomes 15%. @debug desaturate(#f2ece4, 20%); // #eeebe8 // Saturation 20% becomes 0%. @debug desaturate(#d2e1dd, 30%); // #dadada color.grayscale($color) grayscale($color) //=> color @debug color.grayscale(#6b717f); // #757575 @debug color.grayscale(#d2e1dd); // #dadada @debug color.grayscale(#036); // #333333 color.green($color) green($color) //=> number @debug color.green(#e1d7d2); // 215 @debug color.green(white); // 255 @debug color.green(black); // 0 color.hue($color) hue($color) //=> number @debug color.hue(#e1d7d2); // 20deg @debug color.hue(#f2ece4); // 34.2857142857deg @debug color.hue(#dadbdf); // 228deg hwb($hue $whiteness $blackness) hwb($hue $whiteness $blackness / $alpha) hwb($hue, $whiteness, $blackness, $alpha: 1) //=> color @debug hwb(210, 0%, 60%); // #036 @debug hwb(34, 89%, 5%); // #f2ece4 @debug hwb(210 0% 60% / 0.5); // rgba(0, 51, 102, 0.5) color.ie-hex-str($color) ie-hex-str($color) //=> unquoted string @debug color.ie-hex-str(#b37399); // #FFB37399 @debug color.ie-hex-str(#808c99); // #FF808C99 @debug color.ie-hex-str(rgba(242, 236, 228, 0.6)); // #99F2ECE color.invert($color, $weight: 100%) invert($color, $weight: 100%) //=> color @debug color.invert(#b37399); // #4c8c66 @debug color.invert(black); // white @debug color.invert(#550e0c, 20%); // #663b3a lighten($color, $amount) //=> color // Lightness 46% becomes 66%. @debug lighten(#6b717f, 20%); // #a1a5af // Lightness 20% becomes 80%. @debug lighten(#036, 60%); // #99ccff // Lightness 85% becomes 100%. @debug lighten(#e1d7d2, 30%); // white color.lightness($color) lightness($color) //=> number @debug color.lightness(#e1d7d2); // 85.2941176471% @debug color.lightness(#f2ece4); // 92.1568627451% @debug color.lightness(#dadbdf); // 86.4705882353% color.mix($color1, $color2, $weight: 50%) mix($color1, $color2, $weight: 50%) //=> color @debug color.mix(#036, #d2e1dd); // #698aa2 @debug color.mix(#036, #d2e1dd, 75%); // #355f84 @debug color.mix(#036, #d2e1dd, 25%); // #9eb6bf @debug color.mix(rgba(242, 236, 228, 0.5), #6b717f); // rgba(141, 144, 152, 0.75) opacify($color, $amount) fade-in($color, $amount) //=> color @debug opacify(rgba(#6b717f, 0.5), 0.2); // rgba(107, 113, 127, 0.7) @debug fade-in(rgba(#e1d7d2, 0.5), 0.4); // rgba(225, 215, 210, 0.9) @debug opacify(rgba(#036, 0.7), 0.3); // #036 color.red($color) red($color) //=> number @debug color.red(#e1d7d2); // 225 @debug color.red(white); // 255 @debug color.red(black); // 0 saturate($color, $amount) saturate($color, $amount) //=> color // Saturation 50% becomes 70%. @debug saturate(#c69, 20%); // #e05299 // Saturation 35% becomes 85%. @debug desaturate(#f2ece4, 50%); // #ebebeb // Saturation 80% becomes 100%. @debug saturate(#0e4982, 30%) // #004990 color.saturation($color) saturation($color) //=> number @debug color.saturation(#e1d7d2); // 20% @debug color.saturation(#f2ece4); // 30% @debug color.saturation(#dadbdf); // 7.2463768116% color.scale($color, $red: null, $green: null, $blue: null, $saturation: null, $lightness: null, $whiteness: null, $blackness: null, $alpha: null) scale-color(...) //=> color @debug color.scale(#6b717f, $red: 15%); // #81717f @debug color.scale(#d2e1dd, $lightness: -10%, $saturation: 10%); // #b3d4cb @debug color.scale(#998099, $alpha: -40%); // rgba(153, 128, 153, 0.6) transparentize($color, $amount) fade-out($color, $amount) //=> color @debug transparentize(rgba(#6b717f, 0.5), 0.2) // rgba(107, 113, 127, 0.3) @debug fade-out(rgba(#e1d7d2, 0.5), 0.4) // rgba(225, 215, 210, 0.1) @debug transparentize(rgba(#036, 0.3), 0.3) // rgba(0, 51, 102, 0) color.whiteness($color) //=> number @debug color.whiteness(#e1d7d2); // 82.3529411765% @debug color.whiteness(white); // 100% @debug color.whiteness(black); // 0% ==== SASS:LIST ==== list.append($list, $val, $separator: auto) append($list, $val, $separator: auto) //=> list @debug list.append(10px 20px, 30px); // 10px 20px 30px @debug list.append((blue, red), green); // blue, red, green @debug list.append(10px 20px, 30px 40px); // 10px 20px (30px 40px) @debug list.append(10px, 20px, $separator: comma); // 10px, 20px @debug list.append((blue, red), green, $separator: space); // blue red green list.index($list, $value) index($list, $value) //=> number | null @debug list.index(1px solid red, 1px); // 1 @debug list.index(1px solid red, solid); // 2 @debug list.index(1px solid red, dashed); // null list.is-bracketed($list) is-bracketed($list) //=> boolean @debug list.is-bracketed(1px 2px 3px); // false @debug list.is-bracketed([1px, 2px, 3px]); // true list.join($list1, $list2, $separator: auto, $bracketed: auto) join($list1, $list2, $separator: auto, $bracketed: auto) //=> list @debug list.join(10px 20px, 30px 40px); // 10px 20px 30px 40px @debug list.join((blue, red), (#abc, #def)); // blue, red, #abc, #def @debug list.join(10px, 20px); // 10px 20px @debug list.join(10px, 20px, $separator: comma); // 10px, 20px @debug list.join((blue, red), (#abc, #def), $separator: space); // blue red #abc #def @debug list.join([10px], 20px); // [10px 20px] @debug list.join(10px, 20px, $bracketed: true); // [10px 20px] list.length($list) length($list) //=> number @debug list.length(10px); // 1 @debug list.length(10px 20px 30px); // 3 @debug list.length((width: 10px, height: 20px)); // 2 list.separator($list) list-separator($list) //=> unquoted string @debug list.separator(1px 2px 3px); // space @debug list.separator(1px, 2px, 3px); // comma @debug list.separator('Helvetica'); // space @debug list.separator(()); // space list.nth($list, $n) nth($list, $n) @debug list.nth(10px 12px 16px, 2); // 12px @debug list.nth([line1, line2, line3], -1); // line3 list.set-nth($list, $n, $value) set-nth($list, $n, $value) //=> list @debug list.set-nth(10px 20px 30px, 1, 2em); // 2em 20px 30px @debug list.set-nth(10px 20px 30px, -1, 8em); // 10px, 20px, 8em @debug list.set-nth((Helvetica, Arial, sans-serif), 3, Roboto); // Helvetica, Arial, Roboto list.zip($lists...) zip($lists...) //=> list @debug list.zip(10px 50px 100px, short mid long); // 10px short, 50px mid, 100px long @debug list.zip(10px 50px 100px, short mid); // 10px short, 50px mid ==== SASS:MAP ==== map.deep-merge($map1, $map2) //=> map $helvetica-light: ( "weights": ( "lightest": 100, "light": 300 ) ); $helvetica-heavy: ( "weights": ( "medium": 500, "bold": 700 ) ); @debug map.deep-merge($helvetica-light, $helvetica-heavy); // ( // "weights": ( // "lightest": 100, // "light": 300, // "medium": 500, // "bold": 700 // ) // ) @debug map.merge($helvetica-light, $helvetica-heavy); // ( // "weights": ( // "medium: 500, // "bold": 700 // ) // ) map.deep-remove($map, $key, $keys...) //=> map $font-weights: ("regular": 400, "medium": 500, "bold": 700); @debug map.deep-remove($font-weights, "regular"); // ("medium": 500, "bold": 700) $fonts: ( "Helvetica": ( "weights": ( "regular": 400, "medium": 500, "bold": 700 ) ) ); @debug map.deep-remove($fonts, "Helvetica", "weights", "regular"); // ( // "Helvetica": ( // "weights: ( // "medium": 500, // "bold": 700 // ) // ) // ) map.get($map, $key, $keys...) map-get($map, $key, $keys...) $font-weights: ("regular": 400, "medium": 500, "bold": 700); @debug map.get($font-weights, "medium"); // 500 @debug map.get($font-weights, "extra-bold"); // null $fonts: ( "Helvetica": ( "weights": ( "regular": 400, "medium": 500, "bold": 700 ) ) ); @debug map.get($fonts, "Helvetica", "weights", "regular"); // 400 @debug map.get($fonts, "Helvetica", "colors"); // null map.has-key($map, $key, $keys...) map-has-key($map, $key, $keys...) //=> boolean $font-weights: ("regular": 400, "medium": 500, "bold": 700); @debug map.has-key($font-weights, "regular"); // true @debug map.has-key($font-weights, "bolder"); // false $fonts: ( "Helvetica": ( "weights": ( "regular": 400, "medium": 500, "bold": 700 ) ) ); @debug map.has-key($fonts, "Helvetica", "weights", "regular"); // true @debug map.has-key($fonts, "Helvetica", "colors"); // false map.keys($map) map-keys($map) //=> list $font-weights: ("regular": 400, "medium": 500, "bold": 700); @debug map.keys($font-weights); // "regular", "medium", "bold" map.merge($map1, $map2) map-merge($map1, $map2) map.merge($map1, $keys..., $map2) map-merge($map1, $keys..., $map2) //=> map $light-weights: ("lightest": 100, "light": 300); $heavy-weights: ("medium": 500, "bold": 700); @debug map.merge($light-weights, $heavy-weights); // ("lightest": 100, "light": 300, "medium": 500, "bold": 700) $fonts: ( "Helvetica": ( "weights": ( "lightest": 100, "light": 300 ) ) ); $heavy-weights: ("medium": 500, "bold": 700); @debug map.merge($fonts, "Helvetica", "weights", $heavy-weights); // ( // "Helvetica": ( // "weights": ( // "lightest": 100, // "light": 300, // "medium": 500, // "bold": 700 // ) // ) // ) map.remove($map, $keys...) map-remove($map, $keys...) //=> map $font-weights: ("regular": 400, "medium": 500, "bold": 700); @debug map.remove($font-weights, "regular"); // ("medium": 500, "bold": 700) @debug map.remove($font-weights, "regular", "bold"); // ("medium": 500) @debug map.remove($font-weights, "bolder"); // ("regular": 400, "medium": 500, "bold": 700) map.set($map, $key, $value) map.set($map, $keys..., $key, $value) //=> map $font-weights: ("regular": 400, "medium": 500, "bold": 700); @debug map.set($font-weights, "regular", 300); // ("regular": 300, "medium": 500, "bold": 700) $fonts: ( "Helvetica": ( "weights": ( "regular": 400, "medium": 500, "bold": 700 ) ) ); @debug map.set($fonts, "Helvetica", "weights", "regular", 300); // ( // "Helvetica": ( // "weights": ( // "regular": 300, // "medium": 500, // "bold": 700 // ) // ) // ) map.values($map) map-values($map) //=> list $font-weights: ("regular": 400, "medium": 500, "bold": 700); @debug map.values($font-weights); // 400, 500, 700 ==== SASS:MATH ==== === Variáveis === math.$e @debug math.$e; // 2.7182818285 math.$pi @debug math.$pi; // 3.1415926536 === Arredondamentos === math.ceil($number) ceil($number) //=> number @debug math.ceil(4); // 4 @debug math.ceil(4.2); // 5 @debug math.ceil(4.9); // 5 math.clamp($min, $number, $max) //=> number @debug math.clamp(-1, 0, 1); // 0 @debug math.clamp(1px, -1px, 10px); // 1px @debug math.clamp(-1in, 1cm, 10mm); // 10mm math.floor($number) floor($number) //=> number @debug math.floor(4); // 4 @debug math.floor(4.2); // 4 @debug math.floor(4.9); // 4 math.max($number...) max($number...) //=> number @debug math.max(1px, 4px); // 4px $widths: 50px, 30px, 100px; @debug math.max($widths...); // 100px math.min($number...) min($number...) //=> number @debug math.min(1px, 4px); // 1px $widths: 50px, 30px, 100px; @debug math.min($widths...); // 30px math.round($number) round($number) //=> number @debug math.round(4); // 4 @debug math.round(4.2); // 4 @debug math.round(4.9); // 5 === Distância === math.abs($number) abs($number) //=> number @debug math.abs(10px); // 10px @debug math.abs(-10px); // 10px math.hypot($number...) //=> number @debug math.hypot(3, 4); // 5 $lengths: 1in, 10cm, 50px; @debug math.hypot($lengths...); // 4.0952775683in === Exponencial === math.log($number, $base: null) //=> number @debug math.log(10); // 2.302585093 @debug math.log(10, 10); // 1 math.pow($base, $exponent) //=> number @debug math.pow(10, 2); // 100 @debug math.pow(100, 1/3); // 4.6415888336 @debug math.pow(5, -2); // 0.04 math.sqrt($number) //=> number @debug math.sqrt(100); // 10 @debug math.sqrt(1/3); // 0.5773502692 @debug math.sqrt(-1); // NaN === Trigonometria === math.cos($number) //=> number @debug math.cos(100deg); // -0.1736481777 @debug math.cos(1rad); // 0.5403023059 @debug math.cos(1); // 0.5403023059 math.sin($number) //=> number @debug math.sin(100deg); // 0.984807753 @debug math.sin(1rad); // 0.8414709848 @debug math.sin(1); // 0.8414709848 math.tan($number) //=> number @debug math.tan(100deg); // -5.6712818196 @debug math.tan(1rad); // 1.5574077247 @debug math.tan(1); // 1.5574077247 math.acos($number) //=> number @debug math.acos(0.5); // 60deg @debug math.acos(2); // NaNdeg math.asin($number) //=> number @debug math.asin(0.5); // 30deg @debug math.asin(2); // NaNdeg math.atan($number) //=> number @debug math.atan(10); // 84.2894068625deg math.atan2($y, $x) //=> number @debug math.atan2(-1, 1); // 135deg === Unidade === math.compatible($number1, $number2) comparable($number1, $number2) //=> boolean @debug math.compatible(2px, 1px); // true @debug math.compatible(100px, 3em); // false @debug math.compatible(10cm, 3mm); // true math.is-unitless($number) unitless($number) //=> boolean @debug math.is-unitless(100); // true @debug math.is-unitless(100px); // false math.unit($number) unit($number) //=> quoted string @debug math.unit(100); // "" @debug math.unit(100px); // "px" @debug math.unit(5px * 10px); // "px*px" @debug math.unit(5px / 1s); // "px/s" === Outras === math.percentage($number) percentage($number) //=> number @debug math.percentage(0.2); // 20% @debug math.percentage(100px / 50px); // 200% math.random($limit: null) random($limit: null) //=> number @debug math.random(); // 0.2821251858 @debug math.random(); // 0.6221325814 @debug math.random(10); // 4 @debug math.random(10000); // 5373 ==== SASS:META ==== === Mixins === meta.load-css($url, $with: null) // dark-theme/_code.scss $border-contrast: false !default; code { background-color: #6b717f; color: #d2e1dd; @if $border-contrast { border-color: #dadbdf; } } // style.scss @use "sass:meta"; body.dark { @include meta.load-css("dark-theme/code", $with: ("border-contrast": true)); } === Funções === meta.call($function, $args...) call($function, $args...) @use "sass:list"; @use "sass:meta"; @use "sass:string"; /// Return a copy of $list with all elements for which $condition returns 'true' removed. @function remove-where($list, $condition) { $new-list: (); $separator: list.separator($list); @each $element in $list { @if not meta.call($condition, $element) { $new-list: list.append($new-list, $element, $separator: $separator); } } @return $new-list; } $fonts: Tahoma, Geneva, "Helvetica Neue", Helvetica, Arial, sans-serif; content { @function contains-helvetica($string) { @return string.index($string, "Helvetica"); } font-family: remove-where($fonts, meta.get-function("contains-helvetica")); } meta.content-exists() content-exists() //=> boolean @mixin debug-content-exists { @debug meta.content-exists(); @content; } @include debug-content-exists; // false @include debug-content-exists { // true // Content! } meta.feature-exists($feature) feature-exists($feature) //=> boolean @debug meta.feature-exists("at-error"); // true @debug meta.feature-exists("unrecognized"); // false meta.function-exists($name) function-exists($name) //=> boolean @debug meta.function-exists("scale-color"); // true @debug meta.function-exists("add"); // false @function add($num1, $num2) { @return $num1 + $num2; } @debug meta.function-exists("add"); // true meta.get-function($name, $css: false, $module: null) get-function($name, $css: false, $module: null) //=> function @use "sass:list"; @use "sass:meta"; @use "sass:string"; /// Return a copy of $list with all elements for which $condition returns 'true' removed. @function remove-where($list, $condition) { $new-list: (); $separator: list.separator($list); @each $element in $list { @if not meta.call($condition, $element) { $new-list: list.append($new-list, $element, $separator: $separator); } } @return $new-list; } $fonts: Tahoma, Geneva, "Helvetica Neue", Helvetica, Arial, sans-serif; content { @function contains-helvetica($string) { @return string.index($string, "Helvetica"); } font-family: remove-where($fonts, meta.get-function("contains-helvetica")); } meta.global-variable-exists($name, $module: null) global-variable-exists($name, $module: null) //=> boolean @debug meta.global-variable-exists("var1"); // false $var1: value; @debug meta.global-variable-exists("var1"); // true h1 { // $var2 is local. $var2: value; @debug meta.global-variable-exists("var2"); // false } meta.inspect($value) inspect($value) //=> unquoted string @debug meta.inspect(10px 20px 30px); // unquote("10px 20px 30px") @debug meta.inspect(("width": 200px)); // unquote('("width": 200px)') @debug meta.inspect(null); // unquote("null") @debug meta.inspect("Helvetica"); // unquote('"Helvetica"') meta.keywords($args) keywords($args) //=> map @use "sass:meta"; @mixin syntax-colors($args...) { @debug meta.keywords($args); // (string: #080, comment: #800, variable: #60b) @each $name, $color in meta.keywords($args) { pre span.stx-#{$name} { color: $color; } } } @include syntax-colors( $string: #080, $comment: #800, $variable: #60b, ) meta.mixin-exists($name, $module: null) mixin-exists($name, $module: null) //=> boolean @debug meta.mixin-exists("shadow-none"); // false @mixin shadow-none { box-shadow: none; } @debug meta.mixin-exists("shadow-none"); // true meta.module-functions($module) //=> map // _functions.scss @function pow($base, $exponent) { $result: 1; @for $_ from 1 through $exponent { $result: $result * $base; } @return $result; } @use "sass:map"; @use "sass:meta"; @use "functions"; @debug meta.module-functions("functions"); // ("pow": get-function("pow")) @debug meta.call(map.get(meta.module-variables("functions"), "pow"), 3, 4); // 16 meta.module-variables($module) //=> map // _variables.scss $hopbush: #c69; $midnight-blue: #036; $wafer: #e1d7d2; @use "sass:meta"; @use "variables"; @debug meta.module-variables("variables"); // ( // "hopbush": #c69, // "midnight-blue": #036, // "wafer": #e1d7d2 // ) meta.type-of($value) type-of($value) //=> unquoted string @debug meta.type-of(10px); // number @debug meta.type-of(10px 20px 30px); // list @debug meta.type-of(()); // list meta.variable-exists($name) variable-exists($name) //=> boolean @debug meta.variable-exists("var1"); // false $var1: value; @debug meta.variable-exists("var1"); // true h1 { // $var2 is local. $var2: value; @debug meta.variable-exists("var2"); // true } ==== SASS:SELECTOR ==== === Selector Values === @debug ((unquote(".main") unquote("aside:hover")), (unquote(".sidebar") unquote("p"))); // .main aside:hover, .sidebar p selector.is-superselector($super, $sub) is-superselector($super, $sub) //=> boolean @debug selector.is-superselector("a", "a.disabled"); // true @debug selector.is-superselector("a.disabled", "a"); // false @debug selector.is-superselector("a", "sidebar a"); // true @debug selector.is-superselector("sidebar a", "a"); // false @debug selector.is-superselector("a", "a"); // true selector.append($selectors...) selector-append($selectors...) //=> selector @debug selector.append("a", ".disabled"); // a.disabled @debug selector.append(".accordion", "__copy"); // .accordion__copy @debug selector.append(".accordion", "__copy, __image"); // .accordion__copy, .accordion__image selector.extend($selector, $extendee, $extender) selector-extend($selector, $extendee, $extender) //=> selector #{$extender} { @extend #{$extendee}; } @debug selector.extend("a.disabled", "a", ".link"); // a.disabled, .link.disabled @debug selector.extend("a.disabled", "h1", "h2"); // a.disabled @debug selector.extend(".guide .info", ".info", ".content nav.sidebar"); // .guide .info, .guide .content nav.sidebar, .content .guide nav.sidebar selector.nest($selectors...) selector-nest($selectors...) //=> selector @debug selector.nest("ul", "li"); // ul li @debug selector.nest(".alert, .warning", "p"); // .alert p, .warning p @debug selector.nest(".alert", "&:hover"); // .alert:hover @debug selector.nest(".accordion", "&__copy"); // .accordion__copy selector.parse($selector) selector-parse($selector) //=> selector @debug selector.parse(".main aside:hover, .sidebar p"); // ((unquote(".main") unquote("aside:hover")), // (unquote(".sidebar") unquote("p"))) selector.replace($selector, $original, $replacement) selector-replace($selector, $original, $replacement) //=> selector @debug selector.replace("a.disabled", "a", ".link"); // .link.disabled @debug selector.replace("a.disabled", "h1", "h2"); // a.disabled @debug selector.replace(".guide .info", ".info", ".content nav.sidebar"); // .guide .content nav.sidebar, .content .guide nav.sidebar selector.unify($selector1, $selector2) selector-unify($selector1, $selector2) //=> selector | null @debug selector.unify("a", ".disabled"); // a.disabled @debug selector.unify("a.disabled", "a.outgoing"); // a.disabled.outgoing @debug selector.unify("a", "h1"); // null @debug selector.unify(".warning a", "main a"); // .warning main a, main .warning a selector.simple-selectors($selector) simple-selectors($selector) //=> list @debug selector.simple-selectors("a.disabled"); // a, .disabled @debug selector.simple-selectors("main.blog:after"); // main, .blog, :after ==== SASS:STRING ==== string.quote($string) quote($string) //=> string @debug string.quote(Helvetica); // "Helvetica" @debug string.quote("Helvetica"); // "Helvetica" string.index($string, $substring) str-index($string, $substring) //=> number @debug string.index("Helvetica Neue", "Helvetica"); // 1 @debug string.index("Helvetica Neue", "Neue"); // 11 string.insert($string, $insert, $index) str-insert($string, $insert, $index) //=> string @debug string.insert("Roboto Bold", " Mono", 7); // "Roboto Mono Bold" @debug string.insert("Roboto Bold", " Mono", -6); // "Roboto Mono Bold" @debug string.insert("Roboto", " Bold", 100); // "Roboto Bold" @debug string.insert("Bold", "Roboto ", -100); // "Roboto Bold" string.length($string) str-length($string) //=> number @debug string.length("Helvetica Neue"); // 14 @debug string.length(bold); // 4 @debug string.index(""); // 0 string.slice($string, $start-at, $end-at: -1) str-slice($string, $start-at, $end-at: -1) //=> string @debug string.slice("Helvetica Neue", 11); // "Neue" @debug string.slice("Helvetica Neue", 1, 3); // "Hel" @debug string.slice("Helvetica Neue", 1, -6); // "Helvetica" string.to-upper-case($string) to-upper-case($string) //=> string @debug string.to-upper-case("Bold"); // "BOLD" @debug string.to-upper-case(sans-serif); // SANS-SERIF string.to-lower-case($string) to-lower-case($string) //=> string @debug string.to-lower-case("Bold"); // "bold" @debug string.to-lower-case(SANS-SERIF); // sans-serif string.unique-id() unique-id() //=> string @debug string.unique-id(); // uabtrnzug @debug string.unique-id(); // u6w1b1def string.unquote($string) unquote($string) //=> string @debug string.unquote("Helvetica"); // Helvetica @debug string.unquote(".widget:hover"); // .widget:hover
===== EXTENDENDO SELETORES COMPOSTOS =====
// These should both be extended, but they won't be. .message { border: 1px solid black; } .info { font-size: 1.5rem; } .heads-up { @extend .message.info; } .message { border: 1px solid black; } .info { font-size: 1.5rem; } .heads-up { @extend .message, .info; } // Instead of just '.message.info'. %message-info, .message.info { border: 1px solid black; font-size: 1.5rem; } .heads-up { // Instead of '.message.info'. @extend %message-info; }
===== CSS Sintaxe Variada =====
:root { --flex-theme: { border: 1px solid var(--theme-dark-blue); font-family: var(--theme-font-family); padding: var(--theme-wide-padding); background-color: var(--theme-light-blue); }; } $accent-color: #fbbc04; :root { // WRONG, will not work in recent Sass versions. --accent-color-wrong: $accent-color; // RIGHT, will work in all Sass versions. --accent-color-right: #{$accent-color}; } @use "sass:meta"; $font-family-monospace: Menlo, Consolas, "Courier New", monospace; :root { --font-family-monospace: #{meta.inspect($font-family-monospace)}; }
===== OUTROS CONCEITOS =====
Para conceitos de Linha de Comando e API JS, visite o site oficial da linguagem.

Elaborado por Mateus Schwede
ubsocial.github.io