Hvordan jeg lavede et ikonsystem ud af CSS Custom Properties PlatoBlockchain Data Intelligence. Lodret søgning. Ai.

Hvordan jeg lavede et ikonsystem ud af brugerdefinerede CSS-egenskaber

SVG er det bedste format til ikoner på et websted, der findes ingen tvivl om det. Det giver dig mulighed for at have skarpe ikoner uanset skærmens pixeltæthed, du kan ændre stilene på SVG'en, når du svæver, og du kan endda animere ikonerne med CSS eller JavaScript.

Der er mange måder at inkludere en SVG på en side, og hver teknik har sine egne fordele og ulemper. I de sidste par år har jeg brugt en Sass-funktion til at importere mine ikoner direkte i min CSS og undgå at skulle ødelægge min HTML-markering.

Jeg har en Sass-liste med alle kildekoderne til mine ikoner. Hvert ikon kodes derefter ind i en data-URI med en Sass-funktion og gemmes i en tilpasset ejendom på sidens rod.

TL; DR

Det, jeg har til dig her, er en Sass-funktion, der opretter et SVG-ikonbibliotek direkte i din CSS.

SVG-kildekoden er kompileret med Sass-funktionen, der koder dem i data-URI og derefter gemmer ikonerne i CSS-brugerdefinerede egenskaber. Du kan derefter bruge et hvilket som helst ikon hvor som helst i din CSS, som om det var et eksternt billede.

Dette er et eksempel hentet direkte fra koden på mit personlige websted:

.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 teknik har både fordele og ulemper, så tag dem i betragtning, før du implementerer denne løsning på dit projekt:

FORDELE

  • Der er ingen HTTP-anmodninger til SVG-filerne.
  • Alle ikonerne er gemt på ét sted.
  • Hvis du har brug for at opdatere et ikon, behøver du ikke at gennemgå hver HTML-skabelonfil.
  • Ikonerne er cachelagret sammen med din CSS.
  • Du kan manuelt redigere kildekoden til ikonerne.
  • Det forurener ikke din HTML ved at tilføje ekstra markup.
  • Du kan stadig ændre farven eller et aspekt af ikonet med CSS.

ULEMPER

  • Du kan ikke animere eller opdatere en bestemt del af SVG med CSS.
  • Jo flere ikoner du har, jo tungere vil din CSS-kompilerede fil være.

Jeg bruger mest denne teknik til ikoner frem for logoer eller illustrationer. En kodet SVG vil altid være tungere end dens originale fil, så jeg indlæser stadig min komplekse SVG med en ekstern fil enten med en tag eller i min CSS med url(path/to/file.svg).

Indkodning af SVG til data-URI

Det er ikke nyt at kode din SVG som data-URI'er. Faktisk Chris Coyier skrev et indlæg om det for over 10 år siden for at forklare, hvordan du bruger denne teknik, og hvorfor du bør (eller ikke bør) bruge den.

Der er to måder at bruge en SVG i din CSS med data-URI:

  • Som et eksternt billede (ved hjælp af background-image,grænse-billede,liste-stil-billede,...)
  • Som indholdet af et pseudoelement (f.eks ::before or ::after)

Her er et grundlæggende eksempel, der viser, hvordan du bruger disse to metoder:

Hovedproblemet med denne særlige implementering er, at du skal konvertere SVG manuelt, hver gang du har brug for et nyt ikon, og det er ikke rigtig behageligt at have denne lange streng af ulæselig kode i din CSS.

Det er her Sass kommer til undsætning!

Brug af en Sass-funktion

Ved at bruge Sass kan vi gøre vores liv enklere ved at kopiere kildekoden til vores SVG direkte i vores kodebase og lade Sass kode dem korrekt for at undgå browserfejl.

Denne løsning er for det meste inspireret af en eksisterende funktion udviklet af Threespot Media og tilgængelig i deres depot.

Her er de fire trin i denne teknik:

  • Opret en variabel med alle dine SVG-ikoner på listen.
  • Liste over alle de tegn, der skal springes over for en data-URI.
  • Implementer en funktion til at kode SVG'erne til et data-URI-format.
  • Brug din funktion i din kode.

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 funktion

/**
* 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. Tilføj en SVG på din side

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

Hvis du har fulgt disse trin, bør Sass kompilere din kode korrekt og udlæse 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 ");
}		

Brugerdefinerede egenskaber

Den nu implementerede Sass svg() funktion fungerer fremragende. Men dens største fejl er, at et ikon, der er nødvendigt flere steder i din kode, bliver duplikeret og kan øge din kompilerede CSS-filvægt med meget!

For at undgå dette kan vi gemme alle vores ikoner i CSS variabler og brug en reference til variablen i stedet for at udlæse den kodede URI hver gang.

Vi beholder den samme kode, som vi havde før, men denne gang vil vi først udlæse alle ikonerne fra Sass-listen i roden af ​​vores webside:

/**
  * 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)};
  }
}

Nu, i stedet for at ringe til svg() funktion, hver gang vi har brug for et ikon, skal vi bruge den variabel, der blev oprettet med --svg præfiks.

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

Optimering af dine SVG'er

Denne teknik giver ingen optimering af kildekoden til den SVG, du bruger. Sørg for, at du ikke efterlader unødvendig kode; ellers vil de også blive kodet og vil øge din CSS-filstørrelse.

Du kan kontrollere denne store liste af værktøjer og information om, hvordan du optimerer din SVG korrekt. Mit yndlingsværktøj er Jake Archibalds SVGOMG - træk blot din fil derind og kopier den udsendte kode.

Bonus: Opdatering af ikonet ved svævning

Med denne teknik kan vi ikke vælge med CSS specifikke dele af SVG. For eksempel er der ingen måde at ændre på fill farven på ikonet, når brugeren holder musen over knappen. Men der er et par tricks, vi kan bruge med CSS for stadig at være i stand til at ændre udseendet af vores ikon.

For eksempel, hvis du har et sort ikon, og du vil have det hvidt, når du svæver, kan du bruge invert() CSS-filter. Vi kan også lege med hue-rotate() filter.

Det er det!

Jeg håber, du finder denne lille hjælpefunktion praktisk i dine egne projekter. Fortæl mig, hvad du synes om tilgangen - jeg ville være interesseret i at vide, hvordan du kan gøre dette bedre eller tackle det anderledes!

Tidsstempel:

Mere fra CSS-tricks