O mixin responsivo mais usado do Bootstrap. Ele mantém os breakpoints centralizados e deixa o SCSS de componentes grandes muito mais fácil de ler.

@mixin media-breakpoint-up($name, $breakpoints: $grid-breakpoints) {
  $min: breakpoint-min($name, $breakpoints);

  @if $min {
    @media (min-width: $min) {
      @content;
    }
  } @else {
    @content;
  }
}

// Usage
.card-grid {
  display: grid;
  gap: 16px;
  grid-template-columns: 1fr;

  @include media-breakpoint-up(lg) {
    grid-template-columns: repeat(3, 1fr);
  }
}
@mixin media-breakpoint-up($name, $breakpoints: $grid-breakpoints)
  $min: breakpoint-min($name, $breakpoints)

  @if $min
    @media (min-width: $min)
      @content
  @else
    @content

// Usage
.card-grid
  display: grid
  gap: 16px
  grid-template-columns: 1fr

  +media-breakpoint-up(lg)
    grid-template-columns: repeat(3, 1fr)
// Equivalent output
.card-grid {
  display: grid;
  gap: 16px;
  grid-template-columns: 1fr;
}

@media (min-width: 992px) {
  .card-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

Útil quando o layout precisa de um ajuste só para tablets, sem afetar telas pequenas ou grandes.

@mixin media-breakpoint-between($lower, $upper, $breakpoints: $grid-breakpoints) {
  $min: breakpoint-min($lower, $breakpoints);
  $max: breakpoint-max($upper, $breakpoints);

  @media (min-width: $min) and (max-width: $max) {
    @content;
  }
}

// Usage
.toolbar {
  @include media-breakpoint-between(md, lg) {
    gap: 8px;
    flex-wrap: wrap;
  }
}
@mixin media-breakpoint-between($lower, $upper, $breakpoints: $grid-breakpoints)
  $min: breakpoint-min($lower, $breakpoints)
  $max: breakpoint-max($upper, $breakpoints)

  @media (min-width: $min) and (max-width: $max)
    @content

// Usage
.toolbar
  +media-breakpoint-between(md, lg)
    gap: 8px
    flex-wrap: wrap
@media (min-width: 768px) and (max-width: 991.98px) {
  .toolbar {
    gap: 8px;
    flex-wrap: wrap;
  }
}

Junto com make-row() e make-col-ready(), é a forma mais rápida de criar primitivas de grid próprias sobre o sistema do Bootstrap.

@mixin make-col($size: false, $columns: $grid-columns) {
  @if $size {
    flex: 0 0 auto;
    width: percentage(divide($size, $columns));
  } @else {
    flex: 1 1 0;
    max-width: 100%;
  }
}

// Usage
.feature-row {
  @include make-row();
}

.feature-card {
  @include make-col-ready();
  @include make-col(6);

  @include media-breakpoint-up(xl) {
    @include make-col(3);
  }
}
@mixin make-col($size: false, $columns: $grid-columns)
  @if $size
    flex: 0 0 auto
    width: percentage(divide($size, $columns))
  @else
    flex: 1 1 0
    max-width: 100%

// Usage
.feature-row
  +make-row()

.feature-card
  +make-col-ready()
  +make-col(6)

  +media-breakpoint-up(xl)
    +make-col(3)
.feature-row {
  display: flex;
  flex-wrap: wrap;
  margin-inline: -12px;
}

.feature-card {
  width: 50%;
  padding-inline: 12px;
}

@media (min-width: 1200px) {
  .feature-card {
    width: 25%;
  }
}
6/12
6/12
3/12
3/12

Um dos poucos helpers de acessibilidade que toda biblioteca de componentes deveria ter.

@mixin visually-hidden() {
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  margin: -1px !important;
  overflow: hidden !important;
  clip: rect(0, 0, 0, 0) !important;
  white-space: nowrap !important;
  border: 0 !important;
}

// Usage
.icon-button__label {
  @include visually-hidden();
}
@mixin visually-hidden()
  width: 1px !important
  height: 1px !important
  padding: 0 !important
  margin: -1px !important
  overflow: hidden !important
  clip: rect(0, 0, 0, 0) !important
  white-space: nowrap !important
  border: 0 !important

// Usage
.icon-button__label
  +visually-hidden()
.icon-button__label {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

O rótulo para leitores de tela continua acessível, enquanto a interface visível mostra só o ícone.

Um utilitário prático quando é preciso fixar um badge, um ponto, uma alça ou um overlay exatamente no centro visual.

@mixin centerer($horizontal: true, $vertical: true) {
  position: absolute;

  @if ($horizontal and $vertical) {
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
  }
}

// Usage
.badge-dot {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: $accent;

  @include centerer;
}
@mixin centerer($horizontal: true, $vertical: true)
  position: absolute

  @if ($horizontal and $vertical)
    top: 50%
    left: 50%
    transform: translate(-50%, -50%)

// Usage
.badge-dot
  width: 18px
  height: 18px
  border-radius: 50%
  background: $accent
  +centerer
.badge-dot {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

Bom para palavras decorativas em seções hero, tipografia de pôster e rótulos com preenchimento transparente.

@mixin text-outline($color: black, $stroke: 1px) {
  color: transparent;
  -webkit-text-stroke-width: $stroke;
  -webkit-text-stroke-color: $color;
}

// Usage
.hero-word {
  font-size: 72px;
  font-weight: 700;

  @include text-outline(#111827, 1.5px);
}
@mixin text-outline($color: black, $stroke: 1px)
  color: transparent
  -webkit-text-stroke-width: $stroke
  -webkit-text-stroke-color: $color

// Usage
.hero-word
  font-size: 72px
  font-weight: 700
  +text-outline(#111827, 1.5px)
.hero-word {
  font-size: 72px;
  font-weight: 700;
  color: transparent;
  -webkit-text-stroke: 1.5px #111827;
}
CONTORNO

Útil para barras de carregamento, estados de progresso, destaques em skeletons ou qualquer superfície que precise de movimento sem imagens.

@mixin stripes($opacity, $color, $size: 25px, $deg: -135deg) {
  background-size: $size $size;
  background-image: linear-gradient($deg, rgba($color, $opacity) 25%, transparent 25%, transparent 50%, rgba($color, $opacity) 50%, rgba($color, $opacity) 75%, transparent 75%, transparent);
}

// Usage
.loader-track {
  @include stripes(.22, #2563eb, 20px, -45deg);
}
@mixin stripes($opacity, $color, $size: 25px, $deg: -135deg)
  background-size: $size $size
  background-image: linear-gradient($deg, rgba($color, $opacity) 25%, transparent 25%, transparent 50%, rgba($color, $opacity) 50%, rgba($color, $opacity) 75%, transparent 75%, transparent)

// Usage
.loader-track
  +stripes(.22, #2563eb, 20px, -45deg)
.loader-track {
  background-size: 20px 20px;
  background-image: linear-gradient(
    -45deg,
    rgba(37, 99, 235, .22) 25%,
    transparent 25%,
    transparent 50%,
    rgba(37, 99, 235, .22) 50%,
    rgba(37, 99, 235, .22) 75%,
    transparent 75%,
    transparent
  );
}

Um dos helpers personalizados mais fortes. A técnica de máscara o torna especialmente útil para cards premium e destaques.

@mixin border-gradient($color1: #fff, $color2: #fff, $deg: 45deg, $border: 1px) {
  background: linear-gradient($deg, $color1, $color2) border-box;
  -webkit-mask: linear-gradient(#fff 0 0) padding-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  border: $border solid transparent;
}

// Usage
.promo-card {
  border-radius: 16px;
  @include border-gradient(#22c55e, #0ea5e9, 135deg, 1px);
}
@mixin border-gradient($color1: #fff, $color2: #fff, $deg: 45deg, $border: 1px)
  background: linear-gradient($deg, $color1, $color2) border-box
  -webkit-mask: linear-gradient(#fff 0 0) padding-box, linear-gradient(#fff 0 0)
  -webkit-mask-composite: xor
  mask-composite: exclude
  border: $border solid transparent

// Usage
.promo-card
  border-radius: 16px
  +border-gradient(#22c55e, #0ea5e9, 135deg, 1px)
.promo-card {
  border: 1px solid transparent;
  border-radius: 16px;
  background:
    linear-gradient(135deg, #22c55e, #0ea5e9) border-box;
  -webkit-mask:
    linear-gradient(#fff 0 0) padding-box,
    linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
}
Borda de card premium

Um dos helpers mais reutilizáveis que existem. Merece um lugar no topo de qualquer biblioteca Sass interna.

Gere uma versão personalizada com todos os parâmetros necessários em Gerador de clamp()

@function to-clamp($min-size, $max-size, $min-screen: 375px, $max-screen: 1920px) {
  $min-size-rem: math.div($min-size, 16px) * 1rem;
  $max-size-rem: math.div($max-size, 16px) * 1rem;
  // preferred(vw) = (min-size - slope * min-screen) + slope * 100vw
  $slope: math.div($max-size - $min-size, $max-screen - $min-screen);
  $intercept-rem: math.div($min-size - $slope * $min-screen, 16px) * 1rem;
  $slope-vw: $slope * 100 * 1vw;
  @return clamp(#{$min-size-rem}, calc(#{$intercept-rem} + #{$slope-vw}), #{$max-size-rem});
}

// Usage
.headline {
  font-size: to-clamp(28px, 72px);
  margin-bottom: to-rem(24px);
}
@function to-clamp($min-size, $max-size, $min-screen: 375px, $max-screen: 1920px)
  $min-size-rem: math.div($min-size, 16px) * 1rem
  $max-size-rem: math.div($max-size, 16px) * 1rem
  // preferred(vw) = (min-size - slope * min-screen) + slope * 100vw
  $slope: math.div($max-size - $min-size, $max-screen - $min-screen)
  $intercept-rem: math.div($min-size - $slope * $min-screen, 16px) * 1rem
  $slope-vw: $slope * 100 * 1vw
  @return clamp(#{$min-size-rem}, calc(#{$intercept-rem} + #{$slope-vw}), #{$max-size-rem})

// Usage
.headline
  font-size: to-clamp(28px, 72px)
  margin-bottom: to-rem(24px)
.headline {
  font-size: clamp(1.75rem, calc(1.0825rem + 2.85vw), 4.5rem);
  margin-bottom: 1.5rem;
}
Título fluido

Um mixin de controle deslizante reutilizável que centraliza os estilos de trilha, cursor, hover, focus e disabled e deixa cada área do produto ajustar cores e dimensões.

@mixin c-range-styles(
  $track-height: 4px,
  $track-color: $dark-200,
  $thumb-size: 14px,
  $thumb-color: $primary,
  $thumb-border-width: 0,
  $thumb-border-color: transparent,
  $thumb-shadow: none,
  $hover-scale: 1.15,
  $focus-shadow: 0 2px 6px rgba(0, 0, 0, 0.18)
) {
  appearance: none;
  background: transparent;
  cursor: pointer;

  &::-webkit-slider-runnable-track {
    height: $track-height;
    background: $track-color;
    border-radius: 999px;
  }

  &::-webkit-slider-thumb {
    appearance: none;
    width: $thumb-size;
    height: $thumb-size;
    margin-top: math.div($track-height - $thumb-size, 2);
    border-radius: 50%;
    background: $thumb-color;
    border: $thumb-border-width solid $thumb-border-color;
    box-shadow: $thumb-shadow;
  }
}

// Usage
.c-range {
  @include c-range-styles(
    $track-height: 6px,
    $track-color: #dbe3ef,
    $thumb-size: 18px,
    $thumb-color: #111827
  );
}
@mixin c-range-styles(
  $track-height: 4px,
  $track-color: $dark-200,
  $thumb-size: 14px,
  $thumb-color: $primary,
  $thumb-border-width: 0,
  $thumb-border-color: transparent,
  $thumb-shadow: none,
  $hover-scale: 1.15,
  $focus-shadow: 0 2px 6px rgba(0, 0, 0, 0.18)
)
  appearance: none
  background: transparent
  cursor: pointer

  &::-webkit-slider-runnable-track
    height: $track-height
    background: $track-color
    border-radius: 999px

  &::-webkit-slider-thumb
    appearance: none
    width: $thumb-size
    height: $thumb-size
    margin-top: math.div($track-height - $thumb-size, 2)
    border-radius: 50%
    background: $thumb-color
    border: $thumb-border-width solid $thumb-border-color
    box-shadow: $thumb-shadow

// Usage
.c-range
  +c-range-styles(
    $track-height: 6px,
    $track-color: #dbe3ef,
    $thumb-size: 18px,
    $thumb-color: #111827
  )
.c-range {
  appearance: none;
  background: transparent;
}

.c-range::-webkit-slider-runnable-track {
  height: 6px;
  border-radius: 999px;
  background: #dbe3ef;
}

.c-range::-webkit-slider-thumb {
  width: 18px;
  height: 18px;
  margin-top: -6px;
  border-radius: 50%;
  background: #111827;
}

Um único mixin define o posicionamento nos eixos principal e transversal, em vez de declarações de alinhamento espalhadas pelos componentes.

@mixin flex-align($align: center, $justify: center) {
  align-items: $align;
  justify-content: $justify;
}
// $align: flex-start | center | flex-end | stretch | baseline
// $justify: flex-start | center | flex-end | space-between | space-around | space-evenly

// Usage
.toolbar {
  display: flex;
  @include flex-align(center, space-between);
}
@mixin flex-align($align: center, $justify: center)
  align-items: $align
  justify-content: $justify
// $align: flex-start | center | flex-end | stretch | baseline
// $justify: flex-start | center | flex-end | space-between | space-around | space-evenly

// Usage
.toolbar
  display: flex
  +flex-align(center, space-between)
.toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
Filtro Ordenar Exportar Compartilhar

Útil quando a cor e a espessura do contorno dos ícones precisam ser controladas pelo componente pai, e não no markup de cada ícone.

@mixin svg($color, $width) {
  svg {
    path,
    line,
    polyline {
      stroke: $color;
      stroke-width: $width;
    }

    path {
      fill: transparent;
    }
  }
}

// Usage
.icon-wrap {
  @include svg(#111827, 1.5px);
}
@mixin svg($color, $width)
  svg
    path,
    line,
    polyline
      stroke: $color
      stroke-width: $width

    path
      fill: transparent

// Usage
.icon-wrap
  +svg(#111827, 1.5px)
.icon-wrap svg path,
.icon-wrap svg line,
.icon-wrap svg polyline {
  stroke: #111827;
  stroke-width: 1.5px;
}

Um helper prático para projetos que ainda entregam fundos rasterizados em várias resoluções.

@mixin background-image($img, $type: png, $x: 0, $y: 0, $repeat: no-repeat) {
  background-image: url("../images/#{$img}.#{$type}");
  background-image: image-set(
    url("../images/#{$img}.#{$type}") 1x,
    url("../images/#{$img}@2x.#{$type}") 2x,
    url("../images/#{$img}@3x.#{$type}") 3x
  );
  background-repeat: #{$repeat};
  background-position: #{$x}px #{$y}px;
}

// Usage
.hero {
  @include background-image("noise", png, 0, 0, repeat);
}
@mixin background-image($img, $type: png, $x: 0, $y: 0, $repeat: no-repeat)
  background-image: url("../images/#{$img}.#{$type}")
  background-image: image-set(url("../images/#{$img}.#{$type}") 1x, url("../images/#{$img}@2x.#{$type}") 2x, url("../images/#{$img}@3x.#{$type}") 3x)
  background-repeat: #{$repeat}
  background-position: #{$x}px #{$y}px

// Usage
.hero
  +background-image("noise", png, 0, 0, repeat)
.hero {
  background-image: url("../images/noise.png");
  background-repeat: repeat;
  background-position: 0 0;
}
Fundo pronto para Retina

Ainda útil quando você quer manter os seletores de placeholder com prefixo de fornecedor fora dos componentes de formulário.

@mixin placeholder {
  &::-webkit-input-placeholder { @content; }
  &:-moz-placeholder { @content; }
  &::-moz-placeholder { @content; }
  &:-ms-input-placeholder { @content; }
}

// Usage
.input {
  @include placeholder {
    color: rgba($text, .45);
  }
}
@mixin placeholder
  &::-webkit-input-placeholder
    @content
  &:-moz-placeholder
    @content
  &::-moz-placeholder
    @content
  &:-ms-input-placeholder
    @content

// Usage
.input
  +placeholder
    color: rgba($text, .45)
.input::placeholder {
  color: rgba(17, 24, 39, .45);
}

Útil para conjuntos de animações utilitárias, quando você quer passar vários fragmentos de animação como argumentos.

@mixin anim($animate...) {
  $max: length($animate);
  $animations: "";
  @for $i from 1 through $max {
    $animations: #{$animations + nth($animate, $i)};
  }
  animation: $animations;
}

// Usage
.pulse-chip {
  @include anim(fade-in .25s ease, float 2s linear infinite);
}
@mixin anim($animate...)
  $max: length($animate)
  $animations: ""
  @for $i from 1 through $max
    $animations: #{$animations + nth($animate, $i)}
  animation: $animations

// Usage
.pulse-chip
  +anim(fade-in .25s ease, float 2s linear infinite)
.pulse-chip {
  animation: fade-in .25s ease, float 2s linear infinite;
}
Status ao vivo

Útil quando uma borda linear simples parece chapada demais e você quer um brilho concentrado nos cantos.

@mixin border-radial-gradient($color1: #fff, $color2: #fff, $percent: 25%) {
  background: radial-gradient(circle at 0% 0%, $color1 0%, $color2 $percent) border-box, radial-gradient(circle at 100% 100%, $color1 0%, $color2 $percent) border-box;
  -webkit-mask: linear-gradient(#fff 0 0) padding-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
  border: 1px solid transparent;
}

@mixin border-radial-gradient-x2($color1: #fff, $color2: #fff, $percent: 25%) {
  background: radial-gradient(circle at 0% 0%, $color1 0%, $color2 $percent) border-box, radial-gradient(circle at 100% 0%, $color1 0%, $color2 $percent) border-box, radial-gradient(circle at 0% 100%, $color1 0%, $color2 $percent) border-box, radial-gradient(circle at 100% 100%, $color1 0%, $color2 $percent) border-box;
  border: 1px solid transparent;
}

// Usage
.panel {
  @include border-radial-gradient-x2(#7c3aed, #06b6d4, 32%);
}
@mixin border-radial-gradient($color1: #fff, $color2: #fff, $percent: 25%)
  background: radial-gradient(circle at 0% 0%, $color1 0%, $color2 $percent) border-box, radial-gradient(circle at 100% 100%, $color1 0%, $color2 $percent) border-box
  -webkit-mask: linear-gradient(#fff 0 0) padding-box, linear-gradient(#fff 0 0)
  -webkit-mask-composite: xor
  border: 1px solid transparent

@mixin border-radial-gradient-x2($color1: #fff, $color2: #fff, $percent: 25%)
  background: radial-gradient(circle at 0% 0%, $color1 0%, $color2 $percent) border-box, radial-gradient(circle at 100% 0%, $color1 0%, $color2 $percent) border-box, radial-gradient(circle at 0% 100%, $color1 0%, $color2 $percent) border-box, radial-gradient(circle at 100% 100%, $color1 0%, $color2 $percent) border-box
  border: 1px solid transparent

// Usage
.panel
  +border-radial-gradient-x2(#7c3aed, #06b6d4, 32%)
.panel {
  border: 1px solid transparent;
  background: radial-gradient(circle at 0% 0%, #7c3aed 0%, #06b6d4 32%) border-box;
}
Borda de card premium

A variante do projeto, já usada em várias partes da UI; vale mantê-la perto dos outros helpers de superfície reutilizáveis.

@mixin scrollbars($size, $foreground-color, $background-color: mix($foreground-color, white, 50%)) {
  &::-webkit-scrollbar { width: $size; height: $size; }
  &::-webkit-scrollbar-thumb { background: $foreground-color; }
  &::-webkit-scrollbar-track { background: $background-color; }
}

// Usage
.panel {
  @include scrollbars(10px, #111827, #e5e7eb);
}
@mixin scrollbars($size, $foreground-color, $background-color: mix($foreground-color, white, 50%))
  &::-webkit-scrollbar
    width: $size
    height: $size
  &::-webkit-scrollbar-thumb
    background: $foreground-color
  &::-webkit-scrollbar-track
    background: $background-color

// Usage
.panel
  +scrollbars(10px, #111827, #e5e7eb)
.panel::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}

.panel::-webkit-scrollbar-thumb {
  background: #111827;
}

.panel::-webkit-scrollbar-track {
  background: #e5e7eb;
}
Estilos reutilizáveis de barra de rolagem deixam painéis longos fáceis de ler. Estilos reutilizáveis de barra de rolagem deixam painéis longos fáceis de ler. Estilos reutilizáveis de barra de rolagem deixam painéis longos fáceis de ler. Estilos reutilizáveis de barra de rolagem deixam painéis longos fáceis de ler. Estilos reutilizáveis de barra de rolagem deixam painéis longos fáceis de ler. Estilos reutilizáveis de barra de rolagem deixam painéis longos fáceis de ler. Estilos reutilizáveis de barra de rolagem deixam painéis longos fáceis de ler. Estilos reutilizáveis de barra de rolagem deixam painéis longos fáceis de ler.

A variante do projeto para configurar o font-face. Prática para manter um include por família de arquivos.

@mixin font($fname, $fstyle, $fweight, $furl, $fstrech: normal) {
  @font-face {
    font-family: $fname;
    font-style: $fstyle;
    font-weight: $fweight;
    font-stretch: $fstrech;
    src: url($furl) format("woff2");
    font-display: swap;
  }
}

// Usage
@include font("Manrope", normal, 500, "/fonts/manrope-500.woff2");
@mixin font($fname, $fstyle, $fweight, $furl, $fstrech: normal)
  @font-face
    font-family: $fname
    font-style: $fstyle
    font-weight: $fweight
    font-stretch: $fstrech
    src: url($furl) format("woff2")
    font-display: swap

// Usage
+font("Manrope", normal, 500, "/fonts/manrope-500.woff2")
@font-face {
  font-family: "Manrope";
  font-style: normal;
  font-weight: 500;
  src: url("/fonts/manrope-500.woff2") format("woff2");
  font-display: swap;
}
Aa
Título de prévia da fonte

Prático quando você quer listas numeradas estilizadas sem repetir o código padrão do contador em cada componente.

@mixin counter($var, $sep) {
  counter-reset: list + $var;
  > li {
    &:before {
      content: counter(list + $var) $sep;
      counter-increment: list + $var;
    }
  }
}

// Usage
.steps {
  @include counter(step, ". ");
}
@mixin counter($var, $sep)
  counter-reset: list + $var
  > li
    &:before
      content: counter(list + $var) $sep
      counter-increment: list + $var

// Usage
.steps
  +counter(step, ". ")
.steps {
  counter-reset: step;
}

.steps > li::before {
  counter-increment: step;
  content: counter(step) ". ";
}
  1. Reunir os arquivos-fonte
  2. Padronizar os nomes
  3. Exportar os arquivos finais

Um helper decorativo para títulos com volume e textos de marca estilizados.

@mixin text3d($primary, $depth: 5, $shadowsteps: 5, $shadowincrementer: 3px, $shadowopacity: 0.4, $primaryshadowcolour: #000, $lighting: $LIGHTING_CEIL) {
  $predefinedShadows: (
    0 0 5px rgba($primaryshadowcolour, 0.05),
    0 -1px 3px rgba($primaryshadowcolour, 0.2),
    0 3px 5px rgba($primaryshadowcolour, 0.2)
  );
  $value: ();

  @for $i from 1 through $depth {
    $num: $i + px;
    $num1: $i * 1.3 + px;
    $hueadjust: $i * 0.2;

    @if ($lighting == $LIGHTING_FLOOR) {
      $hueadjust: ($i * 2 - $depth - 5) * 1%;
    } @else if ($lighting == $LIGHTING_CEIL) {
      $hueadjust: -($i * 2 + $depth - 10) * 1%;
    } @else if ($lighting == $LIGHTING_FLAT) {
      $hueadjust: -$depth * 1%;
    }

    $colour: adjust-color($primary, $lightness: $hueadjust);
    $theShadow: $num1 $num 1px $colour;
    $value: append($value, $theShadow, comma);
  }

  @for $i from 1 through $shadowsteps {
    @if ($i >= length($predefinedShadows)) {
      $dist: $i * $shadowincrementer;
      $value: append($value, 0 $dist $dist rgba($primaryshadowcolour, $shadowopacity));
    } @else {
      $value: append($value, nth($predefinedShadows, $i));
    }
  }

  text-shadow: $value;
}

// Usage
.logo-mark {
  @include text3d(#f97316, 6, 4, 3px, .18);
}
@mixin text3d($primary, $depth: 5, $shadowsteps: 5, $shadowincrementer: 3px, $shadowopacity: 0.4, $primaryshadowcolour: #000, $lighting: $LIGHTING_CEIL)
  $predefinedShadows: (0 0 5px rgba($primaryshadowcolour, 0.05), 0 -1px 3px rgba($primaryshadowcolour, 0.2), 0 3px 5px rgba($primaryshadowcolour, 0.2))
  $value: ()

  @for $i from 1 through $depth
    $num: $i + px
    $num1: $i * 1.3 + px
    $hueadjust: $i * 0.2

    @if ($lighting == $LIGHTING_FLOOR)
      $hueadjust: ($i * 2 - $depth - 5) * 1%
    @else if ($lighting == $LIGHTING_CEIL)
      $hueadjust: -($i * 2 + $depth - 10) * 1%
    @else if ($lighting == $LIGHTING_FLAT)
      $hueadjust: -$depth * 1%

    $colour: adjust-color($primary, $lightness: $hueadjust)
    $theShadow: $num1 $num 1px $colour
    $value: append($value, $theShadow, comma)

  @for $i from 1 through $shadowsteps
    @if ($i >= length($predefinedShadows))
      $dist: $i * $shadowincrementer
      $value: append($value, 0 $dist $dist rgba($primaryshadowcolour, $shadowopacity))
    @else
      $value: append($value, nth($predefinedShadows, $i))

  text-shadow: $value

// Usage
.logo-mark
  +text3d(#f97316, 6, 4, 3px, .18)
.logo-mark {
  text-shadow: 1px 1px 0 #f59e0b, 2px 2px 0 #ea580c, 0 8px 16px rgba(0,0,0,.12);
}
JINERO

O par de text3d() para caixas, útil para chips, botões e blocos de UI elevados e divertidos.

@mixin box3d($primary, $depth: 5, $shadowsteps: 5, $shadowincrementer: 3px, $shadowopacity: 0.4, $primaryshadowcolour: #000, $lighting: $LIGHTING_CEIL) {
  $predefinedShadows: (
    0 0 5px rgba($primaryshadowcolour, 0.05),
    0 -1px 3px rgba($primaryshadowcolour, 0.2),
    0 3px 5px rgba($primaryshadowcolour, 0.2)
  );
  $value: ();

  @for $i from 1 through $depth {
    $num: $i + px;
    $num1: $i * 1.5 + px;
    $hueadjust: $i * 0.2;

    @if ($lighting == $LIGHTING_FLOOR) {
      $hueadjust: ($i * 2 - $depth - 5) * 1%;
    } @else if ($lighting == $LIGHTING_CEIL) {
      $hueadjust: -($i * 2 + $depth - 10) * 1%;
    } @else if ($lighting == $LIGHTING_FLAT) {
      $hueadjust: -$depth * 1%;
    }

    $colour: adjust-color($primary, $lightness: $hueadjust);
    $theShadow: $num1 $num 1px $colour;
    $value: append($value, $theShadow, comma);
  }

  @for $i from 1 through $shadowsteps {
    @if ($i >= length($predefinedShadows)) {
      $dist: $i * $shadowincrementer;
      $value: append($value, 0 $dist $dist rgba($primaryshadowcolour, $shadowopacity));
    } @else {
      $value: append($value, nth($predefinedShadows, $i));
    }
  }

  box-shadow: $value;
}

// Usage
.chip {
  @include box3d(#8b5cf6, 5, 3, 3px, .16);
}
@mixin box3d($primary, $depth: 5, $shadowsteps: 5, $shadowincrementer: 3px, $shadowopacity: 0.4, $primaryshadowcolour: #000, $lighting: $LIGHTING_CEIL)
  $predefinedShadows: (0 0 5px rgba($primaryshadowcolour, 0.05), 0 -1px 3px rgba($primaryshadowcolour, 0.2), 0 3px 5px rgba($primaryshadowcolour, 0.2))
  $value: ()

  @for $i from 1 through $depth
    $num: $i + px
    $num1: $i * 1.5 + px
    $hueadjust: $i * 0.2

    @if ($lighting == $LIGHTING_FLOOR)
      $hueadjust: ($i * 2 - $depth - 5) * 1%
    @else if ($lighting == $LIGHTING_CEIL)
      $hueadjust: -($i * 2 + $depth - 10) * 1%
    @else if ($lighting == $LIGHTING_FLAT)
      $hueadjust: -$depth * 1%

    $colour: adjust-color($primary, $lightness: $hueadjust)
    $theShadow: $num1 $num 1px $colour
    $value: append($value, $theShadow, comma)

  @for $i from 1 through $shadowsteps
    @if ($i >= length($predefinedShadows))
      $dist: $i * $shadowincrementer
      $value: append($value, 0 $dist $dist rgba($primaryshadowcolour, $shadowopacity))
    @else
      $value: append($value, nth($predefinedShadows, $i))

  box-shadow: $value

// Usage
.chip
  +box3d(#8b5cf6, 5, 3, 3px, .16)
.chip {
  box-shadow: 1px 1px 0 #a78bfa, 2px 2px 0 #8b5cf6, 0 10px 18px rgba(0,0,0,.12);
}
Chip com profundidade

Pequena, mas vale documentar, porque vira parte da linguagem do design system.

@function to-rem($pixels) {
  @return math.div($pixels, 16px) * 1rem;
}

// Usage
.card {
  padding: to-rem(24px);
}
@function to-rem($pixels)
  @return math.div($pixels, 16px) * 1rem

// Usage
.card
  padding: to-rem(24px)
.card {
  padding: 1.5rem;
}
Título fluido

Útil quando você quer espaçamentos ou tamanhos responsivos em uma faixa de largura de tela sem escrever a fórmula calc() para cada propriedade.

@function stripUnit($value) {
  @return $value / ($value * 0 + 1);
}

@mixin fluid(
  $min-value,
  $max-value,
  $min-vw,
  $max-vw,
  $properties...
) {
  @each $property in $properties {
    #{$property}: $min-value;
  }

  @media only screen and (min-width: #{$min-vw}) {
    @each $property in $properties {
      #{$property}: calc(#{$min-value} + #{stripUnit($max-value - $min-value)} * (100vw - #{$min-vw}) / #{stripUnit($max-vw - $min-vw)});
    }
  }

  @media only screen and (min-width: #{$max-vw}) {
    @each $property in $properties {
      #{$property}: $max-value;
    }
  }
}

// Usage
.example {
  @include fluid(20px, 40px, 320px, 1200px, padding-top, margin-bottom);
}
@function stripUnit($value)
  @return $value / ($value * 0 + 1)

@mixin fluid(
  $min-value,
  $max-value,
  $min-vw,
  $max-vw,
  $properties...
)
  @each $property in $properties
    #{$property}: $min-value

  @media only screen and (min-width: #{$min-vw})
    @each $property in $properties
      #{$property}: calc(#{$min-value} + #{stripUnit($max-value - $min-value)} * (100vw - #{$min-vw}) / #{stripUnit($max-vw - $min-vw)})

  @media only screen and (min-width: #{$max-vw})
    @each $property in $properties
      #{$property}: $max-value

// Usage
.example
  +fluid(20px, 40px, 320px, 1200px, padding-top, margin-bottom)
.example {
  padding-top: 20px;
  margin-bottom: 20px;
}

@media only screen and (min-width: 320px) {
  .example {
    padding-top: calc(20px + 20 * (100vw - 320px) / 880);
    margin-bottom: calc(20px + 20 * (100vw - 320px) / 880);
  }
}

@media only screen and (min-width: 1200px) {
  .example {
    padding-top: 40px;
    margin-bottom: 40px;
  }
}
Prévia de espaçamento fluido

Ainda um dos micromixins mais copiados em bibliotecas de componentes e dashboards.

@mixin ellipsis($width: 100%) {
  display: inline-block;
  max-width: $width;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

// Usage
.card-title {
  @include ellipsis(240px);
}
@mixin ellipsis($width: 100%)
  display: inline-block
  max-width: $width
  overflow: hidden
  text-overflow: ellipsis
  white-space: nowrap

// Usage
.card-title
  +ellipsis(240px)
.card-title {
  display: inline-block;
  max-width: 240px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
Este é um título de card muito longo que deve ser cortado com reticências

Um padrão utilitário comum, porque os seletores de barras de rolagem personalizadas são verbosos e se repetem entre aplicativos.

@mixin scrollbars($size, $thumb, $track: rgba($thumb, .2)) {
  &::-webkit-scrollbar {
    width: $size;
    height: $size;
  }

  &::-webkit-scrollbar-thumb {
    background: $thumb;
  }

  &::-webkit-scrollbar-track {
    background: $track;
  }
}

// Usage
.panel {
  @include scrollbars(10px, #111827, #e5e7eb);
}
@mixin scrollbars($size, $thumb, $track: rgba($thumb, .2))
  &::-webkit-scrollbar
    width: $size
    height: $size

  &::-webkit-scrollbar-thumb
    background: $thumb

  &::-webkit-scrollbar-track
    background: $track

// Usage
.panel
  +scrollbars(10px, #111827, #e5e7eb)
.panel::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}

.panel::-webkit-scrollbar-thumb {
  background: #111827;
}

.panel::-webkit-scrollbar-track {
  background: #e5e7eb;
}
Estilos reutilizáveis de barra de rolagem deixam painéis longos fáceis de ler. Estilos reutilizáveis de barra de rolagem deixam painéis longos fáceis de ler. Estilos reutilizáveis de barra de rolagem deixam painéis longos fáceis de ler. Estilos reutilizáveis de barra de rolagem deixam painéis longos fáceis de ler. Estilos reutilizáveis de barra de rolagem deixam painéis longos fáceis de ler. Estilos reutilizáveis de barra de rolagem deixam painéis longos fáceis de ler. Estilos reutilizáveis de barra de rolagem deixam painéis longos fáceis de ler. Estilos reutilizáveis de barra de rolagem deixam painéis longos fáceis de ler.

Use este placeholder em rótulos ou elementos auxiliares da interface em que selecionar texto arrastando não é desejável.

%noselect {
  user-select: none;
}

// Usage
.drag-label {
  @extend %noselect;
}
%noselect
  user-select: none

// Usage
.drag-label
  @extend %noselect
.drag-label {
  user-select: none;
}
Este texto não pode ser selecionado

Aplique um placeholder compartilhado para texto com gradiente em vez de duplicar as declarações de clip e fill.

%text-gradient {
  background-clip: text;
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

// Usage
.brand-word {
  @extend %text-gradient;
  background-image: linear-gradient(135deg, #0ea5e9, #8b5cf6);
}
%text-gradient
  background-clip: text
  -webkit-background-clip: text
  -webkit-text-fill-color: transparent

// Usage
.brand-word
  @extend %text-gradient
  background-image: linear-gradient(135deg, #0ea5e9, #8b5cf6)
.brand-word {
  background-image: linear-gradient(135deg, #0ea5e9, #8b5cf6);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}
Texto em gradiente

Sobre a biblioteca de mixins SCSS

Explore mixins e funções Sass reutilizáveis, com código-fonte, exemplos de uso e prévia ao vivo. Copie qualquer helper para o seu projeto.

Agrupados por finalidade

Mixins e funções estão organizados em grupos lógicos — layout, tipografia, responsividade, cor, animação e outros. Encontre o helper certo na hora.

Prévias ao vivo

Veja o que cada mixin gera antes de copiar. Os painéis de prévia ao vivo mostram o resultado renderizado, para você entender o efeito visual na hora.

Código e uso

Cada item mostra a definição em SCSS junto com exemplos de uso. Copie o código do mixin ou só a linha de include — o que for melhor para o seu fluxo de trabalho.

Cópia em um clique

Copie a definição de qualquer mixin ou exemplo de uso com um único clique. Cole nos seus arquivos SCSS e comece a usar na hora, sem reescrever nada.

Perguntas frequentes

Um mixin é um bloco de código SCSS reutilizável que você define uma vez e inclui em vários seletores com @include. Mixins aceitam parâmetros, o que os torna flexíveis para gerar padrões repetitivos de CSS, como media queries, layouts com flexbox ou animações.

Um mixin gera declarações CSS e é incluído com @include. Uma função calcula e retorna um valor (como uma cor ou um número) e é chamada dentro de uma expressão. Use mixins para blocos de CSS e funções para valores calculados.

Sim. Cada mixin é independente e pode ser copiado para qualquer projeto SCSS. Alguns mixins usam variáveis — basta substituí-las pelos seus valores ou defini-las no seu arquivo de variáveis.

Os mixins duplicam o resultado em cada lugar onde são incluídos, o que pode aumentar o arquivo se usados em excesso. Para declarações compartilhadas, considere usar @extend com seletores placeholder. Mixins são ideais para padrões parametrizados que variam a cada uso.