Sass制作Font Awesome图标

发布于 大漠

Font AwesomeDave Gandy通过字体制作的几百个icons图标。在前端界享有盛名。使用@font-face制作的图标可以随意的放大,并通过CSS中字体相关的CSS对图标进行美化,比如说可以改变图标颜色、大小和增加阴影等,但他也存在一定的弊端。

很多时候,在项目中为了调用整套图标中的某几个时,为了使用Font Awesome制作的图标,我们不得不被迫加载制作icon的所有样式和文件。比如:

.fa-glass:before {
  content: "\f000";
}
.fa-music:before {
  content: "\f001";
}
.fa-search:before {
  content: "\f002";
}
.fa-envelope-o:before {
  content: "\f003";
}
.fa-heart:before {
  content: "\f004";
}
.fa-star:before {
  content: "\f005";
}
...

如此一来,造成文件臃肿,而且有很多冗余没用的代码。

这个时候,我们都在思考,有没有办法能帮助我们,使用Font Awesome图标能按我们所需调用需要图标的样式。换句话说,如果我们需要一个图标,就使用这个图标对应的样式,如果我们需要某几个图标,我们就使用这几个图标对应的样式。看似蛮有意思,那么我们今天,就一起来探讨这个问题。

Sass功能

带着这样的问题,我在想,是否可以使用CSS预处理器语言中的Sass来进行处理。了解Sass的同学都知道,Sass可以进行一些预编码处理,比如说定义mixins、%placeholder等,当需要使用的时候,通过@include和@extend来调用。甚至还可以像其他程序一样,定义函数功能,实现一些自定的功能。那么我们今天就借助Sass的这些特性,来做进一步的思考,是否能通过Sass来帮助我们实现我们前面所说的需求。

实现思路

在Font Awesome字体图库中,每个图标都有一个对应的编码,比如说glass=>"\f000",music=>"\f001"。整个图库我们有近三百个不同的图标,也就是说我们有三百多个这样的实体编码。那么针对这种现像,我们是否可以考虑像其他的程序语言一样,给他们定义一个数组,并将此数组赋值给一个变量。按照这样的思路来说,在Sass中正好具有这样的特性,我们可以将所有图标对应的编码以数组的形式赋值给一个变量。

有了数组就解决我们一大问题,为什么这么说呢?打个比方,我们需要其中的某个图标,我们是否需要一个类似遍历数组的函数,从整个列表中找到需要的东西。也就是说,我们需要在Sass中定义一个遍历数组的函数。

有了变量,也有了遍历功能,能帮助我们找到需要的图标,但我们还需要一些默认的样式功能,比如说,图标怎么调用,这个时候我们就需要通过Sass的mixin来制作,便于每次的调用。

数组、函数和功能都具有了,这个时候我们回到CSS面对的问题中。前面说过,在CSS中使用Font Awesome图库,不管我们需要使用的图标有多少,我们都必须全部加载。而我们真正需要的是要有一个开关——按需开启。也就是说,如果我只需要某几个图标,我能通过一定的方式只开启这几个对应的图标,调出他们对应的样式。如果我们需要所有的图标显示,我也有一个功能开关,可以通过某个功能,一下全部开启。

如此一来,我们的思路就很清楚了,我们使用Sass制作灵活开启图标,需要以下几个东东:

  • 数组:用来定义所有的图标对应的实体编码
  • 引用字体的Mixin:通过mixin,调用@font-face所需的字体
  • 调用单个图标的Mixin:通过这个mixin按需实现单个或某几个图标
  • 调用合部图标的Mixin:通过这个mixin,实现是否开启有所图标
  • 遍历数组的函数:通过这个遍历函数,获取所需要的图标变量

扯了一大通,大家可能想知道的是如何用Sass实现前面说的这一切。那我们现在就开始。

项目结构

为了更好的说明整个实现过程,我们先创建本地创建一个项目,并把制作Font Awesome图标所需要的字体文件引入到项目中。而其中我们同时制作了一个文件夹"sass"来放置.scss文件,并且创建一个文件夹"css",用来放置Sass编译出来的.css文件。整个项目的结构如下所示:

+font-awesome
|-+--fonts
|-|----fontawesome-webfont.eot
|-|----fontawesome-webfont.svg
|-|----fontawesome-webfont.ttf
|-|----fontawesome-webfont.woff
|-+--stylesheets
|-|--+--sass
|-|--+--css

声明数组

在Font Awesome的CSS样式当中,我们能看到一大堆类似于下面的代码:

...
.fa-film:before {
  content: "\f008";
}
.fa-th-large:before {
  content: "\f009";
}
...

而当中每个"\f008"这样的编码就是对应的一个图标,而在Sass中,我们也需要这样的编码,不过不同的是,我们将其以数组的方式定义的。为了能更好的组织这些编码和其他相应的变量,特些在sass目录中创建了一个名叫_variables.scss的文件,并且在这个文件中放置如下所示的代码:

@charset "UTF-8";

//Variables

$fa-css-prefix:                 icon- !default;
$fa-family-name:                "FontAwesome" !default;
$file-path:                     "../../fonts/fontawesome-webfont" !default;

$icons:
    glass                       "\f000",
    music                       "\f001",
    search                      "\f002",
    envelope-o                  "\f003",
    heart                       "\f004",
    star                        "\f005",
    star-o                      "\f006",
    user                        "\f007",
    film                        "\f008",
    th-large                    "\f009",
    th                          "\f00a",
    th-list                     "\f00b",
    check                       "\f00c",
    times                       "\f00d",
    search-plus                 "\f00e",
    search-minus                "\f010",
    power-off                   "\f011",
    signal                      "\f012",
    cog                         "\f013",
    trash-o                     "\f014",
    home                        "\f015",
    file-o                      "\f016",
    clock-o                     "\f017",
    road                        "\f018",
    download                    "\f019",
    arrow-circle-o-down         "\f01a",
    arrow-circle-o-up           "\f01b",
    inbox                       "\f01c",
    play-circle-o               "\f01d",
    repeat                      "\f01e",
    refresh                     "\f021",
    list-alt                    "\f022",
    lock                        "\f023",
    flag                        "\f024",
    headphones                  "\f025",
    volume-off                  "\f026",
    volume-down                 "\f027",
    volume-up                   "\f028",
    qrcode                      "\f029",
    barcode                     "\f02a",
    tag                         "\f02b",
    tags                        "\f02c",
    book                        "\f02d",
    bookmark                    "\f02e",
    print                       "\f02f",
    camera                      "\f030",
    font                        "\f031",
    bold                        "\f032",
    italic                      "\f033",
    text-height                 "\f034",
    text-width                  "\f035",
    align-left                  "\f036",
    align-center                "\f037",
    align-right                 "\f038",
    align-justify               "\f039",
    list                        "\f03a",
    outdent                     "\f03b",
    indent                      "\f03c",
    video-camera                "\f03d",
    picture-o                   "\f03e",
    pencil                      "\f040",
    map-marker                  "\f041",
    adjust                      "\f042",
    tint                        "\f043",
    pencil-square-o             "\f044",
    share-square-o              "\f045",
    check-square-o              "\f046",
    arrows                      "\f047",
    step-backward               "\f048",
    fast-backward               "\f049",
    backward                    "\f04a",
    play                        "\f04b",
    pause                       "\f04c",
    stop                        "\f04d",
    forward                     "\f04e",
    fast-forward                "\f050",
    step-forward                "\f051",
    eject                       "\f052",
    chevron-left                "\f053",
    chevron-right               "\f054",
    plus-circle                 "\f055",
    minus-circle                "\f056",
    times-circle                "\f057",
    check-circle                "\f058",
    question-circle             "\f059",
    info-circle                 "\f05a",
    crosshairs                  "\f05b",
    times-circle-o              "\f05c",
    check-circle-o              "\f05d",
    ban                         "\f05e",
    arrow-left                  "\f060",
    arrow-right                 "\f061",
    arrow-up                    "\f062",
    arrow-down                  "\f063",
    share                       "\f064",
    expand                      "\f065",
    compress                    "\f066",
    plus                        "\f067",
    minus                       "\f068",
    asterisk                    "\f069",
    exclamation-circle          "\f06a",
    gift                        "\f06b",
    leaf                        "\f06c",
    fire                        "\f06d",
    eye                         "\f06e",
    eye-slash                   "\f070",
    exclamation-triangle        "\f071",
    plane                       "\f072",
    calendar                    "\f073",
    random                      "\f074",
    comment                     "\f075",
    magnet                      "\f076",
    chevron-up                  "\f077",
    chevron-down                "\f078",
    retweet                     "\f079",
    shopping-cart               "\f07a",
    folder                      "\f07b",
    folder-open                 "\f07c",
    arrows-v                    "\f07d",
    arrows-h                    "\f07e",
    bar-chart-o                 "\f080",
    twitter-square              "\f081",
    facebook-square             "\f082",
    camera-retro                "\f083",
    key                         "\f084",
    cogs                        "\f085",
    comments                    "\f086",
    thumbs-o-up                 "\f087",
    thumbs-o-down               "\f088",
    star-half                   "\f089",
    heart-o                     "\f08a",
    sign-out                    "\f08b",
    linkedin-square             "\f08c",
    thumb-tack                  "\f08d",
    external-link               "\f08e",
    sign-in                     "\f090",
    trophy                      "\f091",
    github-square               "\f092",
    upload                      "\f093",
    lemon-o                     "\f094",
    phone                       "\f095",
    square-o                    "\f096",
    bookmark-o                  "\f097",
    phone-square                "\f098",
    twitter                     "\f099",
    facebook                    "\f09a",
    github                      "\f09b",
    unlock                      "\f09c",
    credit-card                 "\f09d",
    rss                         "\f09e",
    hdd-o                       "\f0a0",
    bullhorn                    "\f0a1",
    bell                        "\f0f3",
    certificate                 "\f0a3",
    hand-o-right                "\f0a4",
    hand-o-left                 "\f0a5",
    hand-o-up                   "\f0a6",
    hand-o-down                 "\f0a7",
    arrow-circle-left           "\f0a8",
    arrow-circle-right          "\f0a9",
    arrow-circle-up             "\f0aa",
    arrow-circle-down           "\f0ab",
    globe                       "\f0ac",
    wrench                      "\f0ad",
    tasks                       "\f0ae",
    filter                      "\f0b0",
    briefcase                   "\f0b1",
    arrows-alt                  "\f0b2",
    users                       "\f0c0",
    link                        "\f0c1",
    cloud                       "\f0c2",
    flask                       "\f0c3",
    scissors                    "\f0c4",
    files-o                     "\f0c5",
    paperclip                   "\f0c6",
    floppy-o                    "\f0c7",
    square                      "\f0c8",
    bars                        "\f0c9",
    list-ul                     "\f0ca",
    list-ol                     "\f0cb",
    strikethrough               "\f0cc",
    underline                   "\f0cd",
    table                       "\f0ce",
    magic                       "\f0d0",
    truck                       "\f0d1",
    pinterest                   "\f0d2",
    pinterest-square            "\f0d3",
    google-plus-square          "\f0d4",
    google-plus                 "\f0d5",
    money                       "\f0d6",
    caret-down                  "\f0d7",
    caret-up                    "\f0d8",
    caret-left                  "\f0d9",
    caret-right                 "\f0da",
    columns                     "\f0db",
    sort                        "\f0dc",
    sort-down                   "\f0dc",
    sort-asc                    "\f0dd",
    sort-desc                   "\f0de",
    envelope                    "\f0e0",
    linkedin                    "\f0e1",
    undo                        "\f0e2",
    gavel                       "\f0e3",
    tachometer                  "\f0e4",
    dashboard                   "\f0e4",
    comment-o                   "\f0e5",
    comments-o                  "\f0e6",
    bolt                        "\f0e7",
    sitemap                     "\f0e8",
    umbrella                    "\f0e9",
    clipboard                   "\f0ea",
    lightbulb-o                 "\f0eb",
    exchange                    "\f0ec",
    cloud-download              "\f0ed",
    cloud-upload                "\f0ee",
    user-md                     "\f0f0",
    stethoscope                 "\f0f1",
    suitcase                    "\f0f2",
    bell-o                      "\f0a2",
    coffee                      "\f0f4",
    cutlery                     "\f0f5",
    file-text-o                 "\f0f6",
    building-o                  "\f0f7",
    hospital-o                  "\f0f8",
    ambulance                   "\f0f9",
    medkit                      "\f0fa",
    fighter-jet                 "\f0fb",
    beer                        "\f0fc",
    h-square                    "\f0fd",
    plus-square                 "\f0fe",
    angle-double-left           "\f100",
    angle-double-right          "\f101",
    angle-double-up             "\f102",
    angle-double-down           "\f103",
    angle-left                  "\f104",
    angle-right                 "\f105",
    angle-up                    "\f106",
    angle-down                  "\f107",
    desktop                     "\f108",
    laptop                      "\f109",
    tablet                      "\f10a",
    mobile                      "\f10b",
    mobile-phone                "\f10b",
    circle-o                    "\f10c",
    quote-left                  "\f10d",
    quote-right                 "\f10e",
    spinner                     "\f110",
    circle                      "\f111",
    reply                       "\f112",
    github-alt                  "\f113",
    folder-o                    "\f114",
    folder-open-o               "\f115",
    smile-o                     "\f118",
    frown-o                     "\f119",
    meh-o                       "\f11a",
    gamepad                     "\f11b",
    keyboard-o                  "\f11c",
    flag-o                      "\f11d",
    flag-checkered              "\f11e",
    terminal                    "\f120",
    code                        "\f121",
    reply-all                   "\f122",
    mail-reply-all              "\f122",
    star-half-o                 "\f123",
    location-arrow              "\f124",
    crop                        "\f125",
    code-fork                   "\f126",
    chain-broken                "\f127",
    question                    "\f128",
    info                        "\f129",
    exclamation                 "\f12a",
    superscript                 "\f12b",
    subscript                   "\f12c",
    eraser                      "\f12d",
    puzzle-piece                "\f12e",
    microphone                  "\f130",
    microphone-slash            "\f131",
    shield                      "\f132",
    calendar-o                  "\f133",
    fire-extinguisher           "\f134",
    rocket                      "\f135",
    maxcdn                      "\f136",
    chevron-circle-left         "\f137",
    chevron-circle-right        "\f138",
    chevron-circle-up           "\f139",
    chevron-circle-down         "\f13a",
    html5                       "\f13b",
    css3                        "\f13c",
    anchor                      "\f13d",
    unlock-alt                  "\f13e",
    bullseye                    "\f140",
    ellipsis-h                  "\f141",
    ellipsis-v                  "\f142",
    rss-square                  "\f143",
    play-circle                 "\f144",
    ticket                      "\f145",
    minus-square                "\f146",
    minus-square-o              "\f147",
    level-up                    "\f148",
    level-down                  "\f149",
    check-square                "\f14a",
    pencil-square               "\f14b",
    external-link-square        "\f14c",
    share-square                "\f14d",
    compass                     "\f14e",
    caret-square-o-down         "\f150",
    caret-square-o-up           "\f151",
    caret-square-o-right        "\f152",
    eur                         "\f153",
    gbp                         "\f154",
    usd                         "\f155",
    inr                         "\f156",
    jpy                         "\f157",
    rub                         "\f158",
    ruble                       "\f158",
    rouble                      "\f158",
    krw                         "\f159",
    btc                         "\f15a",
    file                        "\f15b",
    file-text                   "\f15c",
    sort-alpha-asc              "\f15d",
    sort-alpha-desc             "\f15e",
    sort-amount-asc             "\f160",
    sort-amount-desc            "\f161",
    sort-numeric-asc            "\f162",
    sort-numeric-desc           "\f163",
    thumbs-up                   "\f164",
    thumbs-down                 "\f165",
    youtube-square              "\f166",
    youtube                     "\f167",
    xing                        "\f168",
    xing-square                 "\f169",
    youtube-play                "\f16a",
    dropbox                     "\f16b",
    stack-overflow              "\f16c",
    instagram                   "\f16d",
    flickr                      "\f16e",
    adn                         "\f170",
    bitbucket                   "\f171",
    bitbucket-square            "\f172",
    tumblr                      "\f173",
    tumblr-square               "\f174",
    long-arrow-down             "\f175",
    long-arrow-up               "\f176",
    long-arrow-left             "\f177",
    long-arrow-right            "\f178",
    apple                       "\f179",
    windows                     "\f17a",
    android                     "\f17b",
    linux                       "\f17c",
    dribbble                    "\f17d",
    skype                       "\f17e",
    foursquare                  "\f180",
    trello                      "\f181",
    female                      "\f182",
    male                        "\f183",
    gittip                      "\f184",
    sun-o                       "\f185",
    moon-o                      "\f186",
    archive                     "\f187",
    bug                         "\f188",
    vk                          "\f189",
    weibo                       "\f18a",
    renren                      "\f18b",
    pagelines                   "\f18c",
    stack-exchange              "\f18d",
    arrow-circle-o-right        "\f18e",
    arrow-circle-o-left         "\f190",
    caret-square-o-left         "\f191",
    toggle-left                 "\f191",
    dot-circle-o                "\f192",
    wheelchair                  "\f193",
    vimeo-square                "\f194",
    try                         "\f195",
    plus-square-o               "\f196";

在这里,每一个图标我们都是用icon-定义类名,比如说icon-glass。那么了为节约时间,在变量中我们特意定义了一个默认变量:

$fa-css-prefix:                 icon- !default;

另外为了调用字体和字体文件方便,因此还定义了另外两个变量:

$fa-family-name:    "FontAwesome" !default;
$file-path:         "../../fonts/fontawesome-webfont" !default;

这样字体font-family定义了名称为“FontAwesome”,而且指定了一个变量$file-path来引用字体文件路径。特别需要注意的是,需要根据项目指定不同的路径。如果您要是使用compass的话,可以通过config.rb文件来指定这个路径。不过这里对此不做过多的描述。

变量$icons是我们最需要的,像其他程序一样,通过以key=>value方式定义了所有图标需要的实体编码。并以数组方式赋值给变量$icons

定义font-face Mixin

要使用字体图标,就离不开@font-face。使用@font-face主要是引用字体,调用特定的字体,这也是最基础的。在此,我们通过定义一个mixin,在需要的就时候使用。

@mixin font-face($font-family,$file-path,$font-weight: normal,$font-style: normal,$asset-pipeline:false){
    @font-face {
        font: {
            family: $font-family;
            weight: $font-weight;
            style: $font-style;
        }

        @if $asset-pipeline == true {
            src: font-url("#{$file-path}.eot");
            src: font-url("#{$file-path}.eot?#iefix") format("embedded-opentype"),
                 font-url("#{$file-path}.woff") format("woff"),
                 font-url("#{$file-path}.ttf") format("truetype"),
                 font-url("#{$file-path}.svg##{$font-family}") format("svg");
        }
        @else {
            src: url("#{$file-path}.eot");
            src: url("#{$file-path}.eot?#iefix") format("embedded-opentype"),
                 url("#{$file-path}.woff") format("woff"),
                 url("#{$file-path}.ttf") format("truetype"),
                 url("#{$file-path}.svg##{$font-family}") format("svg");    
        }
    }
} 

font-face的mixin中,我们传了几个参数给他:

  • $font-family:用来定义自定义的字体名称,在这个示例中指的是“FontAwesome”;
  • $file-path:用来定义引用web字体的路径;
  • $font-weight:用来设置字体的粗细,这里给他传了一个默认参数normal
  • $font-style:用来设置字体的样式,这里给他也传了一个默认参数normal
  • $asset-pipeline:这个主要是用于ruby环境之下,用来定义字体的在Rails下的路径。也就是说asset-pipeline用来替代app/assets/fonts下的fonts。这里也传递了一个参数true

定义好font-face的mixin时,在需要使用@font-face时,只需要通过@include来调用:

@include font-face($fa-family-name,$file-path,normal,normal,$asset-pipeline:false);

在调用的时候也指定了mixin的参数:

  • $fa-family-name:指的是在_variables.scss中定义的变量,其值为“FontAwesome”;
  • $file-path:指的是在_variables.scss中定义的变量,其值为../../fonts/fontawesome-webfont,具体路径需要根据自身项目字体文件的相对路径来进行设置;
  • normal:指的是参数中的font-weightfont-style,并且值都为normal;
  • $asset-pipeline:传了参数为false,表示不使用Rails下指定的字体。其在font-face当中会调用下面对应的代码:
src: url("#{$file-path}.eot");
src: url("#{$file-path}.eot?#iefix") format("embedded-opentype"),
     url("#{$file-path}.woff") format("woff"),
     url("#{$file-path}.ttf") format("truetype"),
     url("#{$file-path}.svg##{$font-family}") format("svg");

上面代码编译出来的CSS:

@font-face {
  font-family: "FontAwesome";
  font-weight: normal;
  font-style: normal;
  src: url("../../fonts/fontawesome-webfont.eot");
  src: url("../../fonts/fontawesome-webfont.eot?#iefix") format("embedded-opentype"), 
        url("../../fonts/fontawesome-webfont.woff") format("woff"), 
        url("../../fonts/fontawesome-webfont.ttf") format("truetype"), 
        url("../../fonts/fontawesome-webfont.svg#FontAwesome") format("svg"); 
}

定义icon Mixin

在Font Awesome中,样式都是通过元素的伪类:before来制作icon样式,如下所示:

  display: inline-block;
  font-family: "FontAwesome";
  font-style: normal;
  font-weight: normal;
  line-height: 1;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale; }

同时为每个不同的icon调用不同的实体编码:

.icon-glass:before {
  content: "\f000"; }

接下来,我们就需要定义一个mixin来实现上述代码等同功能。在这个示例中,定义了icon的mixin。

@mixin icon($position: "before",$styles:true,$icon:false) {
    &:#{$position} {

        @if $icon {
            content: match($icons, $icon);
        }
        @if $styles {
            display: inline-block;
            font: {
                family: $fa-family-name;
                style: normal;
                weight: normal;
            }   
            line-height: 1;
            -webkit-font-smoothing: antialiased;
            -moz-osx-font-smoothing: grayscale;
        }
        @content;
    }
}

在整个icon的mixin中,也设置了三个参数:

  • $position:用来定义伪类,放置icon图标。也就是图标在元素的前面还是后面。这里传了一个默认参数:before。如果你需要放置在元素后面的时候,调用时,可以使用:after。稍后我们可以演示一下。
  • $styles:用来做为是否调用默认样式的参数,这里传默认参数为true,将会调用@if $styles{}中带有的样式;
  • $icon:用来指定icon对应的实体编码。这里传参数为false,如果参数为指定的值时,会自动通过match()函数给对应的图标匹配一个实体编码,并赋值给content

在整个mixin中,还调用了@content,其主要功能就是。如果你想给某个图标设置不同样式时,可以通过他来引用其他样式。

定义好这个mixin,我们就可以通过@include icon和附有具体参数来实现需要的效果:

引用icon需要的样式

[class^="#{$fa-css-prefix}"],
[class*="#{$fa-css-prefix}"] {
    @include icon;
}

上面指的icon定义在:before上,并且指定默认样式,但不引用具体的实体编码,编译出来的CSS如下:

  display: inline-block;
  font-family: "FontAwesome";
  font-style: normal;
  font-weight: normal;
  line-height: 1;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale; }

指定实体编码

每个图标都需要对应的实体编码,字体图标才会起效果,比如说icon-glass对应的是"\f000",这个时候可以按下面的方式调用:

.#{$fa-css-prefix}glass{
    @include icon("before",false,"glass");
}

编译出来的CSS:

.icon-glass:before {
  content: "\f000"; }

很多时候,你可能想让图标放在后面,那么我们可稍做修改来实现:

.#{$fa-css-prefix}music{
    @include icon("after",false,"music");
}

编译出来的CSS:

.icon-music:after {
  content: "\f001"; }

也有的时候,你的图标没有像前面所示的有一个公用的样式(当然这种情况不会存在),这里为了演示说明icon的功能,我们来做一个示例:

.#{$fa-css-prefix}glass{
    @include icon("before",true,"glass");
}

编译出来的CSS:

.icon-glass:before {
  content: "\f000";
  display: inline-block;
  font-family: "FontAwesome";
  font-style: normal;
  font-weight: normal;
  line-height: 1;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale; }

当然,你为了给某个图标有不同的样式,比如说图标更大,或者带有阴影之类,可以通过icon的mixin中的@content功能来实现:

.#{$fa-css-prefix}glass{
    @include icon("before",false,"glass"){
        font-size: 2rem;
        color: green;
        text-shadow: 1px 1px rgba(0,0,0,.5);
    };
}

编译出来的CSS:

.icon-glass:before {
  content: "\f000";
  font-size: 2rem;
  color: green;
  text-shadow: 1px 1px rgba(0, 0, 0, 0.5); }

这也就实现也文章开头所说的,按需开启需要的icons,不会让你的样式文件调用不需要的图标样式。好处就不多说了,上面演示的示例更说明了一切。

macth函数

实现按需开启icon功能,其中macth函数功不可没。因为在Sass中没有类似于map功能的函数。这样一来,就无法像其他程序语言一样,通过key找到其对应的value值。这样一来,按需开启图标一切都是浮云。

不过还好,Hugo大师在Sass中创建了一个match函数,用来模拟map的功能:

@function match($haystack,$needle){
    @each $item in $haystack {
        $index: index($item, $needle);
        @if $index {
            $return: if($index == 1, 2, $index);
            @return nth($item, $return);
        }
    }
    @return false;
}

详细介绍,请点击Mapping with nested lists

定义get-icons mixin

话又说回来,有时候你的可能需要使用很多很多的icons图标,几乎是将里面的图标都用到了,你可能会说,前面的按需开启的方式又会让你觉得不方便,很痛苦。其实不用担心,我们可以定义另一个mixin,并给这个mixin定认一个开关,需要的时候我就开启他,不需要的时候我就不开启他。

在这个get-icons中有两个最为关键,第一给这个mixin定义了一个参数$All-icons,并且默认传参数false,表示默认不开启。另外也个最重要的是通过Sass的@each函数来做循环处理。这个@each主要是针对于数组变量$icons的变量值进行遍历循环。具体代码如下所示:

@mixin get-icons($All-icons:false) {
    @if $All-icons {
        @each $icon in $icons {
            $name: nth($icon, 1);
            .#{$fa-css-prefix}#{$name}{
                @include icon("before",false,$name);
            }
        }
    }
}

有了这个get-icons的mixin,如果你想开启变量$icons指定的所有图标的时候,你只需要按下面的方式来引用:

@include get-icons(true);

编译出来的CSS:

.icon-glass:before {
  content: "\f000"; }
.
.
.
.icon-plus-square-o:before {
  content: "\f196"; }

如何使用

有了这个模块,就算你不使用Font Awesome字体图标,你也可以快速的完成。你唯一需要修改的就是变量文件_variables.scss对应的几个变量:

  • $fa-family-name: 字体名称
  • $file-path:字体路径
  • $icons:字体编码数组,这个非常重要。

修改完成后,其他调用方式如上面所示。当然你的结构中需要有类似下面这样的结构,并且命名要和$icons中的key值对应起来。

<a href="../icon/rub"><i class="icon icon-rub"></i> icon-rub</a>

当然,如果你不想以icon-前缀开头时,也你可以换成别的。别如Font Awesome中就换成了:

<a href="../icon/rub"><i class="fa fa-rub"></i> icon-rub</a>    

这个时候你只需要将$fa-css-prefix变量设置为fa-就行了。有了这一切是不是让你觉得很方便、很简单了。

总结

本文主要通过Sass实现预编码的特性,实现按需开启需要的图标。并在此以著名的字体图标Font Awesome为例。整个功能的实现主要依赖于创建字体编码数值、定义font-faceiconget-icons三个mixin和一个match函数来实现。

如果你有足够多的耐性跟到此处,我想你对这几个功能也有所了解。不过实战是验证真理的最好方式。不仿自己动手一试吧。我想你会有所收获的。如果您有更好的解决方案或者对上面的mixin和function有更好的优化,请在下面的评论中与我们一起分享。

扩展阅读

查看源代码下载代码

如需转载,烦请注明出处:https://www.fedev.cn/preprocessor/create-font-awesome-font-icons-with-sass.html

Lebron Soldier XII 12