Hvordan jeg laget et ikonsystem ut av egendefinerte CSS-egenskaper PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Hvordan jeg laget et ikonsystem av egendefinerte CSS-egenskaper

SVG er det beste formatet for ikoner på et nettsted, det finnes ingen tvil om det. Den lar deg ha skarpe ikoner uansett pikseltetthet på skjermen, du kan endre stilene til SVG når du svever, og du kan til og med animere ikonene med CSS eller JavaScript.

Det er mange måter å inkludere en SVG på en side, og hver teknikk har sine egne fordeler og ulemper. De siste par årene har jeg brukt en Sass-funksjon for å importere ikonene mine direkte til CSS-en min og unngå å rote til HTML-oppmerkingen min.

Jeg har en Sass-liste med alle kildekodene til ikonene mine. Hvert ikon blir deretter kodet inn i en data-URI med en Sass-funksjon og lagret i en tilpasset eiendom på roten av siden.

TL; DR

Det jeg har til deg her er en Sass-funksjon som lager et SVG-ikonbibliotek direkte i CSS-en din.

SVG-kildekoden er kompilert med Sass-funksjonen som koder dem i data-URI og deretter lagrer ikonene i egendefinerte CSS-egenskaper. Du kan deretter bruke et hvilket som helst ikon hvor som helst i CSS-en din, som om det var et eksternt bilde.

Dette er et eksempel hentet rett fra koden til min personlige side:

.c-filters__summary h2:after {
  content: var(--svg-down-arrow);
  position: relative;
  top: 2px;
  margin-left: auto;
  animation: closeSummary .25s ease-out;
}

Demo

Sass struktur

/* All the icons source codes */
$svg-icons: (
  burger: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0...'
);

/* Sass function to encode the icons */
@function svg($name) {
  @return url('data:image/svg+xml, #{$encodedSVG} ');
}

/* Store each icon into a custom property */
:root {
  @each $name, $code in $svg-icons {
    --svg-#{$name}: #{svg($name)};
  }
}

/* Append a burger icon in my button */
.menu::after {
  content: var(--svg-burger);
}		

Denne teknikken har både fordeler og ulemper, så ta dem i betraktning før du implementerer denne løsningen på prosjektet ditt:

Pros

  • Det er ingen HTTP-forespørsler for SVG-filene.
  • Alle ikonene er lagret på ett sted.
  • Hvis du trenger å oppdatere et ikon, trenger du ikke gå over hver HTML-malfil.
  • Ikonene bufres sammen med CSS-en din.
  • Du kan manuelt redigere kildekoden til ikonene.
  • Det forurenser ikke HTML-en din ved å legge til ekstra markering.
  • Du kan fortsatt endre fargen eller et aspekt av ikonet med CSS.

Ulemper

  • Du kan ikke animere eller oppdatere en bestemt del av SVG med CSS.
  • Jo flere ikoner du har, desto tyngre vil den CSS-kompilerte filen være.

Jeg bruker mest denne teknikken for ikoner i stedet for logoer eller illustrasjoner. En kodet SVG vil alltid være tyngre enn den opprinnelige filen, så jeg laster fortsatt den komplekse SVG-en min med en ekstern fil enten med en tag eller i min CSS med url(path/to/file.svg).

Koding SVG til data-URI

Det er ikke nytt å kode SVG-en som data-URI. Faktisk Chris Coyier skrev et innlegg om det for over 10 år siden for å forklare hvordan du bruker denne teknikken og hvorfor du bør (eller ikke bør) bruke den.

Det er to måter å bruke en SVG i din CSS med data-URI:

  • Som et eksternt bilde (ved hjelp av background-image,grense-bilde,liste-stil-bilde,...)
  • Som innholdet i et pseudoelement (f.eks ::before or ::after)

Her er et grunnleggende eksempel som viser hvordan du bruker disse to metodene:

Hovedproblemet med denne spesielle implementeringen er at du må konvertere SVG manuelt hver gang du trenger et nytt ikon, og det er egentlig ikke hyggelig å ha denne lange strengen med uleselig kode i CSS-en din.

Det er her Sass kommer til unnsetning!

Bruke en Sass-funksjon

Ved å bruke Sass kan vi gjøre livet vårt enklere ved å kopiere kildekoden til SVG-en vår direkte i kodebasen vår, og la Sass kode dem riktig for å unngå nettleserfeil.

Denne løsningen er for det meste inspirert av en eksisterende funksjon utviklet av Threespot Media og tilgjengelig i deres depot.

Her er de fire trinnene i denne teknikken:

  • Lag en variabel med alle SVG-ikonene dine oppført.
  • List opp alle tegnene som må hoppes over for en data-URI.
  • Implementer en funksjon for å kode SVG-ene til et data-URI-format.
  • Bruk funksjonen din i koden din.

1. Ikonliste

/**
* Add all the icons of your project in this Sass list
*/
$svg-icons: (
  burger: ''
);

2. Liste over escapede tegn

/**
* Characters to escape from SVGs
* This list allows you to have inline CSS in your SVG code as well
*/
$fs-escape-chars: (
  ' ': '%20',
  ''': '%22',
  '"': '%27',
  '#': '%23',
  '/': '%2F',
  ':': '%3A',
  '(': '%28',
  ')': '%29',
  '%': '%25',
  '': '%3E',
  '': '%5C',
  '^': '%5E',
  '{': '%7B',
  '|': '%7C',
  '}': '%7D',
);

3. Encode funksjon

/**
* You can call this function by using `svg(nameOfTheSVG)`
*/
@function svg($name) {
  // Check if icon exists
  @if not map-has-key($svg-icons, $name) {
    @error 'icon “#{$name}” does not exists in $svg-icons map';
    @return false;
  }

  // Get icon data
  $icon-map: map-get($svg-icons, $name);

  $escaped-string: '';
  $unquote-icon: unquote($icon-map);
  // Loop through each character in string
  @for $i from 1 through str-length($unquote-icon) {
    $char: str-slice($unquote-icon, $i, $i);

    // Check if character is in symbol map
    $char-lookup: map-get($fs-escape-chars, $char);

    // If it is, use escaped version
    @if $char-lookup != null {
        $char: $char-lookup;
    }

    // Append character to escaped string
    $escaped-string: $escaped-string + $char;
  }

  // Return inline SVG data
  @return url('data:image/svg+xml, #{$escaped-string} ');
}		

4. Legg til en SVG på siden din

button {
  &::after {
    /* Import inline SVG */
    content: svg(burger);
  }
}

Hvis du har fulgt disse trinnene, bør Sass kompilere koden på riktig måte og sende ut følgende:

button::after {
  content: url("data:image/svg+xml, %3Csvg%20xmlns=%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox=%270%200%2024.8%2018.92%27%20width=%2724.8%27%20height=%2718.92%27%3E%3Cpath%20d=%27M23.8,9.46H1m22.8,8.46H1M23.8,1H1%27%20fill=%27none%27%20stroke=%27%23000%27%20stroke-linecap=%27round%27%20stroke-width=%272%27%2F%3E%3C%2Fsvg%3E ");
}		

Egendefinerte egenskaper

Den nå implementerte Sass svg() funksjonen fungerer utmerket. Men den største feilen er at et ikon som er nødvendig på flere steder i koden din vil bli duplisert og kan øke vekten av den kompilerte CSS-filen din med mye!

For å unngå dette kan vi lagre alle ikonene våre i CSS-variabler og bruk en referanse til variabelen i stedet for å sende ut den kodede URIen hver gang.

Vi vil beholde den samme koden vi hadde før, men denne gangen vil vi først sende ut alle ikonene fra Sass-listen til roten på nettsiden vår:

/**
  * Convert all icons into custom properties
  * They will be available to any HTML tag since they are attached to the :root
  */

:root {
  @each $name, $code in $svg-icons {
    --svg-#{$name}: #{svg($name)};
  }
}

Nå, i stedet for å ringe svg() funksjon hver gang vi trenger et ikon, må vi bruke variabelen som ble opprettet med --svg prefiks.

button::after {
  /* Import inline SVG */
  content: var(--svg-burger);
}

Optimalisering av SVG-ene dine

Denne teknikken gir ingen optimalisering av kildekoden til SVG-en du bruker. Pass på at du ikke legger igjen unødvendig kode; ellers vil de også bli kodet og vil øke CSS-filstørrelsen.

Du kan sjekke denne flotte listen av verktøy og informasjon om hvordan du kan optimalisere SVG-en på riktig måte. Mitt favorittverktøy er Jake Archibalds SVGOMG - bare dra filen din inn dit og kopier den utsendte koden.

Bonus: Oppdaterer ikonet ved sveving

Med denne teknikken kan vi ikke velge med CSS-spesifikke deler av SVG. For eksempel er det ingen måte å endre fill fargen på ikonet når brukeren holder musepekeren på knappen. Men det er noen få triks vi kan bruke med CSS for fortsatt å kunne endre utseendet til ikonet vårt.

For eksempel, hvis du har et svart ikon og du vil ha det hvitt når du svever, kan du bruke invert() CSS-filter. Vi kan også leke med hue-rotate() filter.

Det er det!

Jeg håper du finner denne lille hjelpefunksjonen nyttig i dine egne prosjekter. Fortell meg hva du synes om tilnærmingen – jeg vil gjerne vite hvordan du kan gjøre dette bedre eller takle det annerledes!

Tidstempel:

Mer fra CSS triks