Skip to content
Snippets Groups Projects
_utils.sass 5.77 KiB
// TODO : ranger

@function px2rem($size)
    $remSize: $size / 16
    @return #{$remSize}rem

@function pxr2rem($size)
    $remSize: $size / 16 / 2
    @return #{$remSize}rem

@mixin in-page-with-aside
    body:not(.full-width) aside ~ .blocks &
        @content

@mixin in-page-without-aside
    main > .blocks &,
    // main > .blocks &,
    body.full-width &,
        @content

@mixin link($color: $link-color)
    color: $color
    text-decoration-color: rgba($color, 0.3)
    text-decoration-line: underline
    text-decoration-thickness: 1px
    text-underline-offset: 3px
    transition: text-decoration-color .3s ease
    &:hover
        text-decoration-color: rgba($color, 1)
        text-decoration-thickness: 1px

@mixin hover-translate-icon($pseudo: after, $distance: 10)
    &::#{$pseudo}
        transition: transform 0.55s $arrow-ease-transition
        transform: translateX(0)
    &:hover
        &::#{$pseudo}
            transform: translateX(#{px2rem($distance)})

@mixin sticky($offset-y: false)
    position: sticky
    top: 0
    @if $header-sticky-enabled
        transition: top $header-sticky-transition
        html:not(.is-scrolling-down) &
            @if $offset-y
                top: calc(var(--header-height) + #{$offset-y})
            @else 
                top: var(--header-height)

// NEW UTILS
@mixin icon($icon-name: '', $pseudo-element: before, $font-size: px2rem(10))
    &::#{$pseudo-element}
        content: map-get($icons, $icon-name)
        display: inline-block
        font-family: 'Icon'
        font-size: $font-size
        font-style: normal
        font-variant: normal
        font-weight: normal
        line-height: 1
        speak: never
        text-transform: none
        vertical-align: middle
        @content // TODO : important de documenter ça

@mixin container
    margin-left: auto
    margin-right: auto
    max-width: $grid-max-width
    padding-left: calc(#{$grid-gutter-sm} / 2)
    padding-right: calc(#{$grid-gutter-sm} / 2)
    width: 100%
    @include media-breakpoint-up(md)
        padding-left: $grid-gutter
        padding-right: $grid-gutter

@mixin grid($cols: 12, $breakpoint: false, $gap-y: $grid-gutter, $gap-x: $grid-gutter)
    @if $breakpoint
        @include media-breakpoint-up($breakpoint)
            display: grid
            grid-gap: $gap-y $gap-x
            grid-template-columns: repeat($cols, 1fr)
    @else
        display: grid
        grid-gap: $gap-y $gap-x
        grid-template-columns: repeat($cols, 1fr)
    @include media-breakpoint-down(md)
        grid-gap: $grid-gutter-sm

// This must be used for content inside columns
@function col($quantity, $base: 12)
    $quantity-on-base: $quantity / $base * 12
    $width: calc( (100% + #{$grid-gutter}) / 12 * #{$quantity-on-base} - #{$grid-gutter} )
    @return #{$width}

// This must be used for offset, outside columns
@function offset($quantity, $base: 12)
    $quantity-on-base: $quantity / $base * 12
    $width: calc( (100% + #{$grid-gutter}) / 12 * #{$quantity-on-base} )
    @return #{$width}

@mixin stretched-link($pseudo-element: after)
    &::#{$pseudo-element}
        bottom: 0
        content: ''
        left: 0
        position: absolute
        right: 0
        top: 0
        z-index: $zindex-stretched-link

@mixin aspect-ratio($ratio, $selector: 'iframe', $background: false)
    @if $background
        aspect-ratio: #{$ratio}
        background: $background
    #{$selector}
        aspect-ratio: #{$ratio}
        display: block
        width: 100%
    @supports not (aspect-ratio: 1)
        position: relative
        &::before
            content: ''
            padding-top: (1 / $ratio) * 100%
            width: 100%
        #{$selector}
            bottom: 0
            left: 0
            position: absolute
            right: 0
            top: 0

@mixin article($background: null)
    position: relative
    display: flex
    flex-direction: column
    .media
        @if $article-media-aspect-ratio
            @include aspect-ratio($article-media-aspect-ratio, 'img', $background)
        margin-bottom: $spacing1
        order: -1
        overflow: hidden
        img
            object-fit: cover
    .title
        font-size: $article-title-size
        margin-bottom: px2rem(5) // faire une variable ?
        @include media-breakpoint-up(md)
            font-size: $article-title-size-md
    a
        @include stretched-link
    p
        margin-bottom: 0
        margin-top: 0


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

@mixin button-reset
    appearance: none
    background: transparent
    border: none
    border-radius: none
    cursor: pointer
    user-select: none
    &:active,
    &:focus
        box-shadow: 0 0 0 0.25rem rgba($main-color, 0.25)
        // TODO : vérifier si l'outline 0 est vraiment nécessaire
        // outline: 0

@mixin list-reset
    list-style: none
    padding-left: 0
    margin-bottom: 0
    margin-top: 0

@mixin inset($top: 0, $right: $top, $bottom: $top, $left: $top)
    inset: $top $right $bottom $left
    // polyfill for inset
    @supports not (inset: $top)
        bottom: $bottom
        left: $left
        right: $right
        top: $top

@function color-contrast($color, $amount)
    @if lightness($color) > 50%
        $amount: $amount * -1
    @return scale-color($color, $lightness: $amount)

@mixin button-icon($icon: false)
    @include button-reset
    line-height: $line-height-base
    border: 1px solid $hero-color
    padding: $spacing0 $spacing1
    white-space: nowrap
    @if $icon
        @include icon($icon, after)
            font-size: px2rem(20) 
            margin-left: px2rem(10)