SemanticUI简介
我来现在就职的这家公司之前,只使用过Bootstrap,并不知道SemanticUI。后来接手了现在的项目之后才知道有这么个框架。相比于盛行的Bootstrap,SemanticUI有它的值得使用的地方。
- SemanticUI 像它的名字一样。更加语义化。
- 默认的样式比Bootstrap好看很多,更加鲜明活泼。个人感觉。
- 类名比Bootstrap短。并且更加离散。嵌套层级也少很多。
但是它有一个很让人头疼的缺点,就是对开发者的种种不友好。
- 文档不够详细,很多模块的使用方法都是寥寥数语,或者放的地方很深。需要依靠你自己的编程经验去猜。
- 模块定制并不像Bootstrap那样可以直接勾选自己需要的模块然后打包。在SemanticUI中,你必须在
npm安装过程中选择要安装哪些模块。 yarn不友好。如上一条,npm中可以在过程中选择安装哪些模块。但是SemanticUI的安装脚本不被yarn所识别。必须yarn add semantic-ui --ignore-scripts才可以。添加了ignore-scriptes选项自然也就丧失了定制化的功能。由于我现在用的框架是RoR,默认使用的前端管理工具就是yarn,所以感觉很难受。
以上只是随便说了说SemanticUI与Bootstrap的区别,并不全面。因为这不是本文主要内容。
定制SemanticUI
有时候我们希望全局地定制SemanticUI。比如SemanticUI的默认字体大小为14px。而我们的项目默认大小为12px。在我接手项目的时候,诸如此类与框架提供样式相悖的样式都是直接在一个init.scss文件中进行覆盖来重置。感觉很丑,也会造成代码的冗余。
但是由于刚接手时并不了解SemanticUI,而且我身为一个前端程序员入职时居然直接让我上手开发Rails应用,手忙脚乱的我全身心都在学Rails根本没时间考虑这个问题。并且,在SemanticUI 官网中不能很容易地找到定制的方法(其实是有的,但是东一块西一块很难系统地贯穿起来)。所以我也就照着原来的样子做了这个项目一年。
init.scss中有些样式难以找到原来定义的地方,覆盖非常困难。chrome-dev-tool看穿了才会在一个六七行的选择器后面找到这个样式的定义,然后加一下权重进行覆盖 —— 就是再写一个六七行甚至七八行的选择器。不想再说了,痛苦。
最近老板发话了,要做前端的大改版。我终于有机会也有时间进行大重构了。过程可能会跟撕痂一样痛苦,但结果一定会跟撕完了一样爽。
如何入手
我是在SemanticUI的Github的src文件夹中看到了这个README.md才知道怎么做的。
里面讲了一些如何重置SemanticUI默认样式,构建适合自己项目的SemanticUI的方法。我一眼就看到了底下的一些关键词reset,font size。惊呆了,原来在这。于是细细地读了起来。
这篇README讲了什么呢?
- 如何构建SemanticUI。直接
gulp install。 - 可以监控文件实时构建。
gulp watch。 - 配置文件的位置。
- 工作流。使用构建工具构建你专属的SemanticUI并在项目中直接使用构建完成的定制包。
- 主题化。
- 定制化。
我们要做的是定制自己的主题,自己的UI规范(字体大小,字体颜色,行高,一级二级三级主题色等等...)。所以我们可以先从5和6入手。
主题与样式的层级关系
主题的定义文件有一定的层级关系:
- SemanticUI的默认主题。就是什么也不设置一路回车然后直接构建直接使用的主题。
- SemanticUI提供的可选的预置的主题包。比如
amazon主题或者material主题。 - 组件自有的主题。比如全局主题色是
#f5f5f5,但是primary按钮组件自己的主题色是蓝色,则以蓝色为准。 - 你自己定制的主题。
某个元素应用的主题,是以上面四条倒序查找的。你自己定制的主题优先,没定制则寻找可选主题。如果没进行任何设置,则使用默认主题。
目录结构
以上的主题都是在哪里定义的呢?我们如何修改它?文中提到了目录结构。
src/definitions文件夹中定义了每个组件使用的js和css。src/themes中存放了SemanticUI提供的所有可用的主题。在我们构建时可以选择一个来使用。默认主题也在这里面。src/site你的专有主题。
源码验证
我们先打开src/semantic.less文件。在文件的最顶部有这样的语句:
& { @import "definitions/globals/reset"; }
这里导入了一个reset文件到当前的semantic.less。我们来看一下reset中都有什么。首先,reset文件的顶部定义了两个变量,一个叫做@type一个叫做@element。
@type : 'global';
@element : 'reset';
紧接着导入了主题配置文件:@import (multiple) '../../theme.config';。在这个配置文件中我们又看到了如下两个变量:
/* Global */
@site : 'default';
@reset : 'default';
...... ......
/*******************************
Folders
*******************************/
/* Path to theme packages */
@themesFolder : 'themes';
/* Path to site override folder */
@siteFolder : 'site/';
注释写的很清楚了,是文件夹路径变量。分别是主题包路径和覆盖文件的路径。这两个路径在哪里被用到了呢?继续看这个文件,在最底部,引入了一个theme.less文件。该文件中有这样一段代码:
/*--------------------
Site Variables
---------------------*/
/* Default site.variables */
@import "@{themesFolder}/default/globals/site.variables";
/* Packaged site.variables */
@import "@{themesFolder}/@{site}/globals/site.variables";
/* Component's site.variables */
@import (optional) "@{themesFolder}/@{theme}/globals/site.variables";
/* Site theme site.variables */
@import (optional) "@{siteFolder}/globals/site.variables";
注释表明是网站变量。里面用到了上一个文件theme.config中定义的四个变量。指向了四个路径引入了四个文件。到这里你应该意识到了,我们重置样式的地方应该就在这些地方。
请注意这四个文件的顺序:
- default网站变量。
- 可选包网站变量。
- 组件自己的变量。
- 你自己定制的网站变量。
由于CSS的特性,层级一样的重复声明的样式是后盖前。所以以上文件以后面的为准。即,最权威的是你自己定义的样式。这与之前所说的主题层级的加载优先级是吻合的。
回顾一下theme.config。这里定义的变量:
/* Path to theme packages */
@themesFolder : 'themes';
/* Path to site override folder */
@siteFolder : 'site/';
我们便知道这四个路径都指到哪里了。既然以我们自定义的主题为准,那么我们直接看@import (optional) "@{siteFolder}/globals/site.variables";也就是site/globals/site.variables。里面空空如也,只有一句注释:用户全局变量。找到了!我们只要在这里重置样式就可以了。
定位到文件了,该如何书写呢?面对空空如也的文件无从下手?通常面对这种情况,最好的做法是看它默认的文件是怎么写的。
打开src/themes/default/globals/site.variables,看到下面几个代码片段,你就会茅塞顿开:
@fontName : 'Lato';
......
@emSize : 14px;
@fontSize : 14px;
......
@primaryColor : @blue;
@secondaryColor : @black;
......
以字体大小为例,如果我们要更改我们全局的字体大小,以12px为基准。我们回到我们空空的site/globals/site.variables文件。添加如下代码:
@emSize : 12px;
@fontSize : 12px;
这样我们就完成了样式覆盖,使用12px作为基准字体大小了。
举一反三
我们已经会了如何定制全局的样式。那么一些特殊化的定制要如何完成呢?比如,全局字体大小为12px,但是产品和UI要求了,所有的按钮内字体都要是14px。
其实根据上面的经验,我们的做法还是一样的。
首先打开src/site/elements/button.variables。熟悉的一幕又出现了:只有一句注释。再打开src/themes/default/elements/button.variables又看到了令人兴奋的片段(别想歪):
/* Button */
@verticalMargin: 0em;
@horizontalMargin: 0.25em;
@backgroundColor: #E0E1E2;
@backgroundImage: none;
@background: @backgroundColor @backgroundImage;
@lineHeight: 1em;
咋整?回到那个空文件进行变量覆盖呀~就这么简单。
最后一步
已经对默认的样式进行覆盖了,是时候打包我们自己的SemanticUI了!
gulp clean
gulp build
打包成功后使用时会发现,样式乖乖的都按规定走了。再也不用写七八行的选择器了。爽。再见了init.scss。
讨论
有的人说了,既然都动了源码,干嘛不直接在src/themes/default/elements/button.variables改了算了。有两个原因不这么做:
- 不讲道理的原因:官方说了你最好在自己的重置文件里写。
- 因为你在自己的重置文件里写,知道自己重置了哪些样式,而直接修改原来的,就啥也不知道了。
学会了这种方式以后,你就可以基于SemanticUI进行“二次开发”,打造适合你的SemanticUI框架。