제퍼넷 로고

CSS 사용자 정의 속성에서 아이콘 시스템을 만드는 방법

시간

SVG는 웹사이트의 아이콘에 가장 적합한 형식입니다. 그것에 대해 의심의 여지가 없다. 이를 통해 화면 픽셀 밀도에 관계없이 선명한 아이콘을 가질 수 있으며, 호버링 시 SVG 스타일을 변경할 수 있으며 CSS 또는 JavaScript로 아이콘에 애니메이션을 적용할 수도 있습니다.

페이지에 SVG를 포함하는 방법에는 여러 가지가 있으며 각 기술에는 고유한 장점과 단점이 있습니다. 지난 몇 년 동안 저는 Sass 기능을 사용하여 CSS에서 아이콘을 직접 가져오고 HTML 마크업을 엉망으로 만들 필요가 없었습니다.

내 아이콘의 모든 소스 코드가 포함된 Sass 목록이 있습니다. 그런 다음 각 아이콘은 Sass 기능을 사용하여 데이터 URI로 인코딩되고 사용자 정의 속성 페이지의 루트에 있습니다.

TL; DR

여기서 제가 준비한 것은 CSS에서 직접 SVG 아이콘 라이브러리를 생성하는 Sass 함수입니다.

SVG 소스 코드는 데이터 URI로 인코딩한 다음 CSS 사용자 정의 속성에 아이콘을 저장하는 Sass 기능으로 컴파일됩니다. 그런 다음 외부 이미지인 것처럼 CSS의 아무 곳에서나 아이콘을 사용할 수 있습니다.

이것은 내 개인 사이트의 코드에서 직접 가져온 예입니다.

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

Rescale과 함께 비즈니스를 가속화하는 방법에 대해 알아보세요.

사스 구조

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

이 기술에는 장단점이 모두 있으므로 프로젝트에 이 솔루션을 구현하기 전에 이를 고려하십시오.

장점

  • SVG 파일에 대한 HTTP 요청이 없습니다.
  • 모든 아이콘은 한 곳에 저장됩니다.
  • 아이콘을 업데이트해야 하는 경우 각 HTML 템플릿 파일을 검토할 필요가 없습니다.
  • 아이콘은 CSS와 함께 캐시됩니다.
  • 아이콘의 소스 코드를 수동으로 편집할 수 있습니다.
  • 추가 마크업을 추가하여 HTML을 오염시키지 않습니다.
  • CSS를 사용하여 아이콘의 색상이나 일부 측면을 변경할 수 있습니다.

단점

  • CSS를 사용하여 SVG의 특정 부분에 애니메이션을 적용하거나 업데이트할 수 없습니다.
  • 아이콘이 많을수록 CSS 컴파일 파일이 더 무거워집니다.

로고나 일러스트레이션보다는 아이콘에 이 기법을 주로 사용합니다. 인코딩된 SVG는 항상 원본 파일보다 무거우므로 복잡한 SVG를 외부 파일과 함께 로드합니다. 태그 또는 내 CSS에서 url(path/to/file.svg).

SVG를 데이터 URI로 인코딩

SVG를 데이터 URI로 인코딩하는 것은 새로운 것이 아닙니다. 사실로 Chris Coyier이 게시물을 작성했습니다. 이 기술을 사용하는 방법과 사용해야 하는(또는 사용하지 말아야 하는) 이유를 설명하기 위해 10년 이상 전에 이에 대해 설명했습니다.

데이터 URI가 있는 CSS에서 SVG를 사용하는 방법에는 두 가지가 있습니다.

  • 외부 이미지로(사용 background-image,테두리 이미지,목록 스타일 이미지,…)
  • 의사 요소의 내용으로(예: ::before or ::after)

다음은 이 두 가지 방법을 사용하는 방법을 보여주는 기본 예입니다.

이 특정 구현의 주요 문제는 새 아이콘이 필요할 때마다 SVG를 수동으로 변환해야 하고 CSS에 읽을 수 없는 긴 문자열이 있는 것이 정말 즐겁지 않다는 것입니다.

Sass가 구출하러 온 곳입니다!

Sass 함수 사용

Sass를 사용하면 SVG의 소스 코드를 코드베이스에 직접 복사하여 Sass가 브라우저 오류를 방지하기 위해 적절하게 인코딩하도록 함으로써 삶을 더 단순하게 만들 수 있습니다.

이 솔루션은 주로 Threespot Media에서 개발한 기존 기능에서 영감을 얻었으며 다음에서 사용할 수 있습니다. 그들의 저장소.

이 기술의 XNUMX단계는 다음과 같습니다.

  • 모든 SVG 아이콘이 나열된 변수를 만듭니다.
  • 데이터 URI에 대해 건너뛰어야 하는 모든 문자를 나열합니다.
  • SVG를 데이터 URI 형식으로 인코딩하는 기능을 구현합니다.
  • 코드에서 함수를 사용하십시오.

1. 아이콘 목록

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

2. 이스케이프 문자 목록

/**
* 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. 인코딩 기능

/**
* 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. 페이지에 SVG 추가

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

이러한 단계를 따랐다면 Sass는 코드를 올바르게 컴파일하고 다음을 출력해야 합니다.

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 ");
}		

사용자 정의 속성

현재 구현된 Sass svg() 기능이 잘 작동합니다. 그러나 가장 큰 결점은 코드의 여러 위치에 필요한 아이콘이 중복되어 컴파일된 CSS 파일의 무게가 많이 증가할 수 있다는 것입니다!

이를 피하기 위해 모든 아이콘을 다음 위치에 저장할 수 있습니다. CSS 변수 매번 인코딩된 URI를 출력하는 대신 변수에 대한 참조를 사용합니다.

이전과 동일한 코드를 유지하지만 이번에는 먼저 Sass 목록의 모든 아이콘을 웹 페이지의 루트에 출력합니다.

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

이제 전화하는 대신 svg() 아이콘이 필요할 때마다 함수를 사용하여 생성된 변수를 사용해야 합니다. --svg 접두사.

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

SVG 최적화

이 기술은 사용 중인 SVG의 소스 코드에 대한 최적화를 제공하지 않습니다. 불필요한 코드를 남기지 않도록 하십시오. 그렇지 않으면 인코딩도 되며 CSS 파일 크기가 늘어납니다.

확인할 수 있습니다 이 훌륭한 목록 SVG를 적절하게 최적화하는 방법에 대한 도구 및 정보. 내가 가장 좋아하는 도구는 Jake Archibald의 SVGOMG — 거기에 파일을 드래그하고 출력된 코드를 복사하기만 하면 됩니다.

보너스: 마우스 오버 시 아이콘 업데이트

이 기술을 사용하면 SVG의 CSS 특정 부분을 선택할 수 없습니다. 예를 들어 변경할 방법이 없습니다. fill 사용자가 버튼을 가리킬 때 아이콘의 색상입니다. 그러나 여전히 아이콘의 모양을 수정할 수 있도록 CSS와 함께 사용할 수 있는 몇 가지 트릭이 있습니다.

예를 들어 검은색 아이콘이 있고 마우스를 가져가면 흰색으로 표시하려면 다음을 사용할 수 있습니다. invert() CSS 필터. 우리는 또한 놀 수 있습니다 hue-rotate() 필터.

그게 다야!

이 작은 도우미 기능이 자신의 프로젝트에서 유용하기를 바랍니다. 접근 방식에 대해 어떻게 생각하는지 알려주세요. 이 방식을 개선하거나 다르게 처리하는 방법을 알고 싶습니다!

spot_img

최신 인텔리전스

spot_img

우리와 함께 채팅

안녕하세요! 어떻게 도와 드릴까요?