With the development of front-end technology, icons in web pages are no longer limited to < img > tags. There are many implementation methods, such as Sprites (commonly known as sprite chart), Icon Font (Font Icon), SVG, etc. Bootstrap, a front-end framework known to engineers, uses these technologies to implement its icon library.
This paper first introduces various implementation methods of Bootstrap Icons, and then the principle and implementation of GrowingIO Design Icons.
Bootstrap Icons
<img>
Displaying icons through < img > tags is the most primitive and simplest implementation method. To achieve the effect shown in the figure above, you only need to insert the following code in HTML:
<img src="/assets/img/bootstrap.svg" alt="Bootstrap" width="32" height="32">
However, this method also has a disadvantage: it takes a long time to wait for an HTTP session before the picture is displayed. When a page has several icons, this time is very long.
Sprites
In order to solve the problems mentioned above, Sprite map came into being. Suppose the following figure is the three icons to be displayed on the page:
The implementation code is as follows:
<svg width="32" height="32" fill="currentColor"> <use xlink:href="bootstrap-icons.svg#heart-fill"/> </svg> <svg width="32" height="32" fill="currentColor"> <use xlink:href="bootstrap-icons.svg#toggles"/> </svg> <svg width="32" height="32" fill="currentColor"> <use xlink:href="bootstrap-icons.svg#shop"/> </svg>
The principle of Sprite chart is to summarize all icons into one file, and then implement it through CSS cut or SVG's < symbol >. No matter how many icons are displayed, there will only be one HTTP session.
Although the number of HTTP sessions is reduced to one through Sprites, its download time is still when the icon is displayed for the first time, and users still need to wait for the download of this large file.
Icon font
The emergence of @ font face in CSS provides ideas for solving the above problems@ Font face CSS at rule specifies a custom font used to display text. The font can be loaded from a remote server or a font installed locally by the user. The method of use is as follows:
@font-face { font-family: "bootstrap-icons"; src: url("./fonts/bootstrap-icons.woff2?a97b3594ad416896e15824f6787370e0") format("woff2"), url("./fonts/bootstrap-icons.woff?a97b3594ad416896e15824f6787370e0") format("woff"); }
The following icons are displayed:
The HTML code is as follows:
<i style="font-size: 2rem; color: cornflowerblue;"></i>
After that, it can be used to preload the font file:
<link rel="preload" href="./fonts/bootstrap-icons.woff2?a97b3594ad416896e15824f6787370e0" as="font" type="font/woff2">
Icon font although preloading can be used, an HTTP session is still required. Is there a way to avoid additional HTTP sessions?
SVG
At this time, we have to mention SVG, because the definition of SVG can be embedded in HTML code with < SVG > tag. For example, the following Icon:
Its SVG code is:
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" viewBox="0 0 16 16"> <path fill-rule="evenodd" d="M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z"/> </svg>
In this way, only the HTML page is loaded, and no additional HTTP request is required to load the file.
GrowingIO Design Icons
Based on the above technical comparison, GrowingIO Design Icons adopts SVG implementation. However, it needs to be used in conjunction with GrowingIO Design, which is positioned as the React component library, so SVG needs to be converted into React components. This also brings some benefits:
- Converting SVG to React components can reduce some redundant SVG styles.
- After being converted to React component, it is easier to control the style of SVG.
- You can use Babel tools to implement on-demand reference, or packaging tools such as Webpack to optimize packaging volume.
Conversion tool
After the implementation method is determined, the next question is: how can the front-end engineer automatically convert the SVG file into React component after getting it from the designer?
Here we will introduce a new tool - SVGR. Use it to convert the Logo file of GrowingIO:
The code obtained is as follows:
import * as React from "react"; function SvgComponent(props: React.SVGProps<SVGSVGElement>) { return ( <svg width= height= fill="none" {...props}> <path d="M33.563 7.528c-.008.09-.008.183-.016.27v.011a8.823 8.823 0 01-.98 3.57c-.415.04-1.294.133-1.606.29-.406.183-.77.449-1.082.788-.32.356-.563.77-.742 1.22-.168.456-.258.949-.258 1.452v7.391c-.508.125-1.031.2-1.574.23a9.886 9.886 0 01-.344.008h-.383a9.042 9.042 0 01-1.5-.152V8.141a8.925 8.925 0 013.645-1.191h.156V8.39s1.61-.945 3.941-.91c.14.004.285.008.438.02.101.003.203.015.304.027zM77.012 1.684v3.043c-.028 0-.059.004-.09.004a9.055 9.055 0 00-3.727 1.086V2.762a8.955 8.955 0 013.707-1.074c.035-.004.075-.004.11-.004zM77.012 6.961v15.485c-.035.011-.075.015-.11.027a8.71 8.71 0 01-1.87.196 8.262 8.262 0 01-1.825-.192L73.195 8.09a8.989 8.989 0 013.817-1.129zM94.27 13.247v9.242a8.98 8.98 0 01-1.817.18 8.967 8.967 0 01-1.988-.22v-7.417c0-.055 0-.102-.012-.153a4.151 4.151 0 00-.262-1.316 3.672 3.672 0 00-.734-1.207 3.35 3.35 0 00-1.078-.797 2.991 2.991 0 00-2.586-.027c-.012.011-.04.015-.059.027a3.545 3.545 0 00-1.082.797 3.953 3.953 0 00-.734 1.207 4.258 4.258 0 00-.262 1.469v7.441a8.915 8.915 0 01-1.87.196c-.665 0-1.313-.07-1.934-.212V8.047c1.87-1.152 3.379-1.117 3.804-1.066v1.777a6.839 6.839 0 012.082-1.09 6.92 6.92 0 011.403-.285c.191-.011.386-.023.593-.023.168 0 .329.004.489.02a6.712 6.712 0 012.242.558c1.914.863 3.687 2.809 3.804 5.309zM71.832 7.368l-2.707 7.734-2.617 7.453-.047.137c-.04.008-.074.012-.113.02-.633.12-1.27.18-1.918.18-.192 0-.383-.005-.57-.02a7.926 7.926 0 01-1.297-.18l-.672-2.32-1.028-3.555-.707-2.445-.43 1.488-1.566 5.375-.406 1.39c-.309.067-.613.11-.922.141a10.124 10.124 0 01-2.945-.113l-.043-.11-2.57-7.707-2.497-7.476a8.872 8.872 0 011.95-.211c.722 0 1.418.086 2.093.246l.813 2.582 2.156 6.828 1.688-6.61.722-2.827a8.946 8.946 0 011.98-.22c.665 0 1.31.071 1.93.212l.782 3.078 1.605 6.367 2.242-6.812.844-2.559a8.978 8.978 0 012.254-.285 9.06 9.06 0 011.996.219z" fill="#161C3A" /> <path d="M117.945.016v22.402c-.035.008-.066.02-.101.024a8.66 8.66 0 01-1.867.2 8.3 8.3 0 01-1.832-.196V1.122c1.835-1.157 3.328-1.157 3.8-1.106z" fill="#FF671B" /> <path d="M41.324 18.676a3.828 3.828 0 01-3.828-3.824 3.825 3.825 0 017.648 0c0 2.11-1.71 3.824-3.82 3.824zm0-11.687a7.866 7.866 0 100 15.73c4.34 0 7.86-3.523 7.86-7.867a7.861 7.861 0 00-7.86-7.863zM23.7 11.551c0 5.106-3.512 9.426-8.34 10.86a12.23 12.23 0 01-3.512.508C5.305 22.919 0 17.829 0 11.55c0-.144.004-.293.012-.437C.246 5.04 5.457.188 11.848.188c2.75 0 5.277.895 7.28 2.402l.032-.03c.414.304.809.636 1.18.995a8.976 8.976 0 01-4.445 1.988l.015-.011a7.618 7.618 0 00-4.062-1.153c-3.977 0-7.23 2.973-7.47 6.735a8.166 8.166 0 00-.01.437c0 3.969 3.347 7.184 7.48 7.184.351 0 .695-.027 1.03-.066 2.43-.325 4.49-1.766 5.587-3.762h-6.043a8.917 8.917 0 011.234-3.793h10.031c.004.144.012.293.012.437zM102.98 19.172a3.66 3.66 0 01-3.664-3.66 3.66 3.66 0 013.664-3.656 3.656 3.656 0 013.657 3.656 3.657 3.657 0 01-3.657 3.66zm4.141-11.082v.77a7.686 7.686 0 10.012 13.203v.879c.008.023.008.055.008.082 0 .039 0 .078-.008.113a3.272 3.272 0 01-2.406 3.043 3.25 3.25 0 01-3.036-.695c-.003.004-.003.004-.003 0a9.122 9.122 0 00-.461-.012c-.164 0-.321.004-.481.016-.035 0-.074 0-.113.004a8.748 8.748 0 00-2.727.617 6.882 6.882 0 006.141 3.758 6.867 6.867 0 003.996-1.274 6.903 6.903 0 002.871-4.949c.016-.164.024-.324.024-.492V6.958a8.997 8.997 0 00-3.817 1.132z" fill="#161C3A" /> <path d="M131.062 18.274a6.878 6.878 0 01-6.874-6.879 6.88 6.88 0 016.874-6.879 6.883 6.883 0 016.883 6.879 6.88 6.88 0 01-6.883 6.879zm0-18.125c-6.207 0-11.246 5.031-11.246 11.246 0 6.211 5.039 11.25 11.246 11.25 6.215 0 11.254-5.039 11.254-11.25 0-6.215-5.039-11.246-11.254-11.246z" fill="#FF671B" /> </svg> ); } export default SvgComponent;
Through this example, we can know that SVGR can meet our needs. Next, we will introduce how to manage several icons.
Icon management
├── package.json ├── src ├── svgs └── templates
- svgs stores the SVG files provided by the designer;
- src converts the SVG file into the React code and stores it in the src directory.
The front-end engineer gets the SVG file and puts it in the svgs directory, and then runs the command:
$ npx @svgr/cli --out-dir src svgs
So far, most of our work has been completed. However, in practical application, there will be the need for custom styles.
custom style
In order to meet various scenarios, you need to make some modifications to the style. For example, the following scenarios:
- The icon needs to have a background, and the background color is different in different states;
- The color of the icon can be customized;
- The icon can be rotated all the time;
- Icons can be customized in size.
In the code structure, add a layer of < span > tag outside the < SVG > tag, which can be used to set the background.
<span> <svg viewBox="0 0 64 64" fill="currentColor" width="1rem" height="1rem"> ... </svg> <span>
Then define CSS styles through GIO icon to realize the style effects such as Hover, Click and Disable.
Summary
By analyzing the principles of various implementation methods of Bootstrap Icons, as the technical selection of GrowingIO Design Icons, this paper finally selects SVG mode, and then explains the implementation method of GrowingIO Design Icons in detail.
reference resources
GitHub - growingio/gio-design-icons: GrowingIO Design SVG Icons
Getting Started - SVGR
Bootstrap Icons · Official open source SVG icon library for Bootstrap