1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        Web圖標工程化方案

        共 13058字,需瀏覽 27分鐘

         ·

        2021-05-31 12:42

        點擊上方關注 前端技術江湖一起學習,天天進步


        來源:周周醬愛學習

        https://juejin.cn/post/6952150039732944910


        如何管理圖標是我們在web項目開發(fā)過程中都會遇到的問題。隨著web技術的發(fā)展,圖標方案也經(jīng)歷了幾個階段,以下這幾種圖標方案也基本能涵蓋web圖標使用的歷程。

        image sprite

        最早通過img標簽或background-image來引用圖標,每個圖標單獨引用,后來為了減少http的請求,提高網(wǎng)站性能,提出sprite的概念,將小的 png 圖片合并到一張圖上,然后根據(jù) background-position 來顯示不同的圖片。

        優(yōu)勢:

        1. 兼容性好
        2. 還原度高

        劣勢:

        1. 同一圖標的不同顏色需要設計多個圖片
        2. 新增圖標需要重新合成sprite
        3. 由于是位圖,兼容不同分辨率需要多套尺寸

        iconfont

        為了更易于控制圖標顏色和大小,并兼容各種設備屏幕,后來開始出現(xiàn)iconfont方案。iconfont就是圖標字體,我們可以像使用普通字體一樣使用它,只要適合字體相關的CSS屬性都適合字體圖標,使用font-size和color就可以輕松控制圖標的大小和顏色。隨著各種字體圖標庫網(wǎng)站的出現(xiàn),國外的icomoon.io,或者國內阿里的iconfont.cn,帶來的全套解決方案,使iconfont流行起來。

        優(yōu)勢:

        1. 能夠容易地改變圖標的顏色,尺寸
        2. 矢量圖不失真
        3. 兼容所有流行的瀏覽器,在h5和app上都能使用
        4. 替換圖標和新增圖標也非常簡單,也不需要考慮圖標合并的問題

        劣勢:

        1. 只支持單色圖標
        2. 字體渲染,低倍屏下容易出現(xiàn)鋸齒

        引用方式

        iconfont的使用方式也很簡單,使用 @font-face 引入字體格式,就和使用其他自定義字體一樣。

        @spicons-font-path"./fonts";
        @font-face {
         font-family"spicons";
         srcurl('@{spicons-font-path}/spicons.eot?v=1');
         srcurl('@{spicons-font-path}/spicons.eot?v=1#iefix'format('eot'),
             url('@{spicons-font-path}/spicons.ttf?v=1'format('truetype'),
          url('@{spicons-font-path}/spicons.woff?v=1'format('woff'),
          url('@{spicons-font-path}/spicons.svg?v=1#spicons'format('svg');
        }
        .sp-icon {
         font-family"spicons";
            display: inline-block;
            font-style: normal;
            font-weight: normal;
            font-variant: normal;
            text-transform: none;
            text-rendering: auto;
            line-height1;
            -webkit-font-smoothing: antialiased;
            -moz-osx-font-smoothing: grayscale;
        }
        復制代碼
        • unicode 引用
        <div class="sp-icon">&#xE001;</div>
        復制代碼
        • 使用配套生成的樣式
        <link rel="stylesheet" href="./iconfont.css">
        <span class="sp-icon icon-xxx"></span>
        復制代碼

        工程化方式

        依賴網(wǎng)站生成字體文件,在替換或加圖標后需要重新覆蓋項目中的圖標css代碼,不夠自動化。可以使用工具腳本在本地項目中將SVG文件生成iconfont,更方便地管理項目圖標。需要在項目中安裝以下依賴庫。

        • gulp (自動化構建工具)
        • gulp-iconfont (使用gulp將svg圖標集合創(chuàng)建為 svg/ttf/eot/woff/woff2字體)
        • gulp-iconfont-css (結合gulp-iconfont生成配套的css樣式)

        gulpfile

        var gulp = require('gulp');
        var iconfont = require('gulp-iconfont');
        var iconfontCss = require('gulp-iconfont-css');

        /** 生成圖標字體文件*/
        gulp.task('Iconfont'function({
            return gulp
                .src(['../src/icons/svg/*.svg'])
                .pipe(
                    iconfontCss({
                        fontName'spicons'//字體名
                        path'../src/icons/templates/iconFont.less'//模板文件路徑
                        targetPath'../spicons-icons.less',//樣式文件目標地址相對于dest目錄
                        cssClass'sp-icon' //樣式類名
                    })
                )
                .pipe(
                    iconfont({
                        fontName'spicons'// required
                        formats: ['ttf''eot''woff''svg']
                    })
                )
                .pipe(gulp.dest('../src/styles/iconfont/fonts'));
        });


        gulp.task('default',gulp.series('Iconfont'));
        復制代碼

        gulp-iconfont-css支持使用自定義的css模板,來組織生成的字體配套樣式,以靈活的方式創(chuàng)建符合項目規(guī)范的樣式命名,引用路徑。

        • less模板
        @spicons-font-path"./fonts";
        @font-face {
         font-family"<%= fontName %>";
         srcurl('@{spicons-font-path}/<%= fontName %>.eot?v=1');
         srcurl('@{spicons-font-path}/<%= fontName %>.eot?v=1#iefix'format('eot'),
             url('@{spicons-font-path}/<%= fontName %>.ttf?v=1'format('truetype'),
          url('@{spicons-font-path}/<%= fontName %>.woff?v=1'format('woff'),
          url('@{spicons-font-path}/<%= fontName %>.svg?v=1#<%= fontName %>'format('svg');
        }

        .<%= cssClass%> {
         font-family"<%= fontName %>";
            display: inline-block;
            font-style: normal;
            font-weight: normal;
            font-variant: normal;
            text-transform: none;
            text-rendering: auto;
            line-height1;
            -webkit-font-smoothing: antialiased;
            -moz-osx-font-smoothing: grayscale;
        }

        <% _.each(glyphsfunction(glyph) { %>@icon-<%= glyph.fileName.replace(/[\d]{1,}([\-])/, "") %>: "\<%= glyph.codePoint %>";
        <% }); %>

        .<%= cssClass%>-char(@icon-variable) {
         content: @@icon-variable;
        }

        .<%= cssClass%>-base-pseudo(@filename, @insert: before) {
         @pseudo-selector: ~":@{insert}";
            @icon-variable: ~"icon-@{filename}";
         &@{pseudo-selector} {
          .<%= cssClass%>-char(@icon-variable);
         }
        }

        <% _.each(glyphsfunction(glyph) { 
            %>.<%= cssClass%>-<%= glyph.fileName.replace(/[\d]{1,}([\-])/, "") %> {
         .<%= cssClass%>-base-pseudo(<%= glyph.fileName.replace(/[\d]{1,}([\-])/, "") %>);
        }
        <% }); %>
        復制代碼
        • 執(zhí)行構建圖標命令gulp \--gulpfile build/build-icon.js

        • 生成字體圖標以及樣式文件

        微信圖片_20191214224749.png
        • 樣式文件
        微信圖片_20191231153104.png

        svg sprite

        svg意為可縮放矢量圖形,它不會像位圖一樣因為放大而失真,他在不同分辨率下的表現(xiàn)都一樣清晰。svg其實很早就出現(xiàn)了,只不過由于兼容性的問題,早前并沒有很好地發(fā)揮出它的價值,但隨著IE6/7/8退出舞臺, android 4.x 的開始,很多網(wǎng)站都開始使用svg作為圖標方案 。github在16年的時候已經(jīng)使用svg替代iconfont,ant design在 3.9.0 之后,使用了 svg圖標替換了原先的 font 圖標。

        優(yōu)勢:

        1. 能夠容易地改變圖標的顏色,尺寸
        2. 支持彩色圖標
        3. 矢量圖不失真
        4. 可讀性好,有利于SEO與無障礙
        5. 渲染效果好,不會有鋸齒

        劣勢:

        1. 體積相對于iconfont較大

        引入方式

        1. 使用img、object、embed標簽或者作為background背景圖直接引用svg,或者可以合并成雪碧圖,這種方式與png雪碧圖使用方法一樣。
        2. inline svg,svg本身是一個html標簽,可以直接把svg寫入 html中。
        <body>
          <div>
            <svg>....</svg>
          </div>
        </body>
        復制代碼
        1. 使用 svg中的 symbol,use 元素來制作圖標

        標記的作用是定義一個圖像模板,本身不會輸出任何圖像,可以使用標記實例化它。在實際項目中我們會有很多圖標,將零散的svg合并,每個圖標有唯一的symbol,通過symbol來引用。將symbol定義插入到頁面body中,然后在需要使用的地方通過引用。將xlink:href設置為定義的symbol id即可。

        <svg style="display: none;">
         <symbol viewBox="0 0 16 16" id="icon-bell">
          <path fill="#ffa896" d="M14,12 L15.5,12 C15.7761424,12 16,12.2238576 16,12.5 C16,12.7761424 15.7761424,13 15.5,13 L0.5,13 C0.223857625,13 3.38176876e-17,12.7761424 0,12.5 C-3.38176876e-17,12.2238576 0.223857625,12 0.5,12 L0.5,12 L2,12 L2,6 C2,2.6862915 4.6862915,6.08718376e-16 8,0 C11.3137085,-6.08718376e-16 14,2.6862915 14,6 L14,12 Z M3,12 L13,12 L13,6 C13,3.23857625 10.7614237,1 8,1 C5.23857625,1 3,3.23857625 3,6 L3,12 Z M8,16 C6.8954305,16 6,15.1045695 6,14 C7,14 9,14 10,14 C10,15.1045695 9.1045695,16 8,16 Z"></path>
         </symbol>
          <symbol viewBox="0 0 16 16" id="icon-arrow-up">
          <path fill="#ffa896" d="M413.1,327.3l-1.8-2.1l-136-156.5c-4.6-5.3-11.5-8.6-19.2-8.6c-7.7,0-14.6,3.4-19.2,8.6L101,324.9l-2.3,2.6  C97,330,96,333,96,336.2c0,8.7,7.4,15.8,16.6,15.8v0h286.8v0c9.2,0,16.6-7.1,16.6-15.8C416,332.9,414.9,329.8,413.1,327.3z"></path>
         </symbol>
        </svg>
        復制代碼
        <svg>
         <use xlink:href="#icon-arrow-up"/> 
        </svg>
        <svg>
         <use xlink:href="#icon-bell"/> 
        </svg>
        復制代碼
        微信圖片_20191215160410.png

        symbol可以寫入到body中,同時可以使用外鏈引用,不過使用外鏈的方式在IE下兼容性不是很好。

        <svg>
         <use xlink:href="/assets/svg-symbols.svg#icon-arrow-up"/> 
        </svg>
        復制代碼

        工程化方式

        手動中合成引入那一坨 symbol 模板是不方便的,我們需要的是自動管理圖標。隨著 webpack 打包的成熟,各種 loader的出現(xiàn),為我們提供了成熟的方案。

        • svg-sprite-loader

        針對所引用的svg文件,svg-sprite-loader會把你的icon塞到一個個symbol中,最終在你的body中嵌入合并后的symbol。

        示例項目使用vue cli 3搭建,vue.config.js相關配置如下,我們會將圖標文件放在一個特定的目錄中,針對該目錄下的文件,會將默認的loader配置排除,使用svg-sprite-loader。

        chainWebpack:config=> {  
                config.module
                  .rule('svg')
                  .exclude.add(resolve('src/icons'))
                  .end()
                config.module
                  .rule('icons')
                  .test(/\.svg$/)
                  .include.add(resolve('src/icons'))
                  .end()
                  .use('svg-sprite-loader')
                  .loader('svg-sprite-loader')
                  .options({
                    symbolId'icon-[name]'
                  })
                  .end()
              }
        復制代碼
        • 批量引入圖標文件
        const req = require.context('/src/icons'true, /\.svg$/)
        const requireAll = requireContext => requireContext.keys().map(requireContext)
        requireAll(req)
        復制代碼
        • 運行項目后可以看到body中插入了svg symbol
        微信圖片_20191215163114.png
        • 我們就可以在頁面中使用這些圖標了,同時可以封裝通用icon調用組件,將圖標name,size,color都作為參數(shù),就能方便控制圖標的使用。
        <template>
        <i :style="styles" :class="iconClass">
          <svg class="svg-icon" aria-hidden="true" v-on="$listeners">
            <use :xlink:href="iconName" />
          </svg>
        </i>
        </template>

        <script>
        export default {
          name'SvgIcon',
          props: {
            typeString,
            size: [NumberString],
            colorString,
            className:String
          },
          computed: {
            iconName() {
              return `#icon-${this.type}`
            },
            iconClass() {
              if (this.className) {
                return 'icon ' + this.className
              } else {
                return 'icon'
              }
            },
            styles() {
              let style = {}
              if (this.size) {
                style['font-size'] = `${this.size}px`
              }
              if (this.color) {
                style.color = this.color
              }
              return style
            },
          },
        }
        </script>
        <style scoped>
        .icon{
          display: inline-block;
          line-height0;
        }
        .svg-icon {
          width1em;
          height1em;
          fill: currentColor;
          overflow: hidden;
          vertical-align: middle;
        }
        </style>
        復制代碼
        <svg-icon type="bell" size="60" color="#ffa896"/>
        復制代碼
        微信圖片_20191215163745.png

        小結

        各方案有利有弊,一套方案不一定能兼容全部場景,這一切都取決于項目實際情況和瀏覽器的支持情況,符合具體使用場景的解決方案才是好方案。

        The End

        歡迎自薦投稿到《前端技術江湖》,如果你覺得這篇內容對你挺有啟發(fā),記得點個 「在看」支持下~

        點個『在看』支持下 

        瀏覽 70
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            灌红酒+惩罚+调教+高潮h | 中文字幕11 | 亚洲成人黄色电影在线观看 | 亚洲精品国产成人综合久久久久久久久 | 性受 XXXX黑人XYX性爽 | 激情乱伦AV | 少妇放荡的呻吟干柴烈火图片 | 国产精品嫩草久久久久yw193 | 欧美综合一区二区 | 欧美日大香蕉 |