想象一下这样的场景,你在历经千辛万苦终于把网站做好了,你的上司或者你的客户思考良久告诉你,我觉得这个按钮颜色可以再鲜艳一点,这个卡片的边角再圆一点,我要想把我的主色调从#88ED14换成#1FC600。。。
这绝对不是臆想,而是99.99%会出现的问题。你把按钮1的颜色改了,发现还要改按钮2,按钮3。你把这一页卡片的圆角半径border-radius从5px改为15px,发现还有30个页面也有卡片,而你要一个一个去改,做着无数重复又没有意义的工作。5天过后,领导过来告诉你,这个卡片我觉得还是之前的更好看,这个还是太圆了。
而这一切产生的原因,可能是你的建站工具选择不好,可能是你的工作流程从一开始就不对。如果从一开始就搭建好了你自己的设计体系,这里面很多的“问题”都可以在几乎一瞬间完成。
不方便维护网站的案例
我来举两个实际的例子,下面图一是三个客户反馈的三个卡片,为了保护隐私我把文字内容都换掉了。可以看到,我找到卡片一的border-radius把他取消之后,也就是变为0,其他两个卡片还是有8px的border-radius,这也就意味着你要更改的时候得要一个卡片一个卡片找到border-radius去修改。
方便维护网站的案例
下图是我找的苹果官网的一个卡片设置,第一张是正常状态下的卡片样式,通过查看CSS可以知道这个是18px的border-radius。
我尝试找到一个卡片把border-radius取消,你可以看到,所有的这三张卡片同时发生了变化,全部没有了圆角效果,这便是很直观的可维护性上的差距。同样的道理,你也可以试试卡片的阴影效果box-shadow。
接着下面展示的是一个我自己制作的网站,可以看到,我如果想改变该网站的主色调,只需要改变一个地方就行了。同样的,我修改border-radius,只在一个地方修改就可以把所有的页面的样式一次同步更新了,而不单单是你看到的本页面。毫无疑问,这样的设置在后期维护的方便性上不言而喻。
CSS 自定义属性/变量(CSS variables)
下面引入的这个概念非常重要,了解和熟练使用CSS variables能让你的网站设计水平更上一个台阶,而这也正是我标题中说的设计体系搭建必备的知识。那么什么是CSS variables?
自定义属性的定义
CSS variables,中文叫做CSS自定义属性(或者变量),是由 CSS 开发者自行定义的,你可以在文档中重复使用他们。由自定义属性标记设定值,由 var() 函数来获取值。
全局变量和局部变量
CSS变量不仅仅可以在全局 :root
中声明,它也可以在CSS文件中的任何时候声明,比如在一个CSS的代码块中指定变量。
全局变量(Global scope variables):当你在全局范围内声明 CSS 变量时,可以在 HTML 文档的任何地方访问到它。全局变量通常定义在根伪类 :root
下。比如说我们的网站主色调primary color,字体大小,用于按钮的强调色action color或者accent color,字体颜色,网站的宽度,边距等等。。。
:root {
--primary-color: #ff5733; /* 全局可复用 */
--button-radius: 15px; /* 全局可复用 */
}
局部变量(Local scope variables):要创建具有局部作用域的变量,我们需要在要使用它的选择器内声明它。局部变量仅在该范围内可访问使用。
header {
--background-color: #ff5633; /* 仅header范围内可复用 */
--header-height: 100px; /* 仅header范围内可复用 */
}
.article-card {
--border-radius: 10px; /* 仅在class .article-card范围内可复用 */
--card-padding: 24px; /* 仅在class .article-card范围内可复用 */
}
如何创建一个 CSS 自定义属性
其实上面的代码已经展示了变量的样子,创建自定义属性,也叫做变量的声明。声明一个自定义属性,属性名需要以两个减号(--
)开始,属性值则可以是任何有效的 CSS 值。它们与color、height、font-size这些正式属性没有什么不同,举例如下:
:root {
--brand-color: #3D85C6;
--font-size: 1.125rem;
--heading-color: green;
--card-logo-size: 30px;
}
属性如何命名,通常我们常规的做法是使用有意义的英语来命名,不要简单到你自己几个月后都不认识了,也不要复杂到一眼玩不到尾,比如我们看到 --button-radius
就知道这是一个给按钮的border radius的一个自定义属性。
这里特别注意了!CSS 变量名称是大小写敏感的,比如 --font-size
和 --Font-Size
是两个不同的变量。
如何使读取CSS 自定义变量,var() 函数
var()
函数可以代替元素中任何属性中的值(value)的任何部分。var()函数的语法如下:
var(--name, value)
Name是必需的,变量名称必须以两个减号开头。
value是非必需的。 是一个回退值,如果未找到变量则使用该值。比如 var(--primary-color)
是有效的。
要在另一个选择器中使用(读取)上面声明的全局变量,我们按以下方式编写:
header {
backgroundd-color: var(--primary-color);
}
相信看到这里你会慢慢明白,为什么我们要在前期花这么多的精力来创建这些变量,我们花的这些时间的工作会在日后的开发,维护中成倍的节省时间。想改变颜色,只需要在相对应的颜色变量中修改数值,而不用去做重复的复制粘贴工作。
我的自定义设置
每一个人都有他自己习惯的自定义设置,相信在你熟悉用法之后你也会有自己的体系了,下面我分享一下我自己习惯的设置作为一个参考。请注意,这里面有些数值你不能直接复制过去使用,因为涉及到不同尺寸下数值是不一样的。
首先我们看一个基础款的设置:
:root {
/** colors 颜色体系 **/
/* 主色调 */
--color-primary: #6bc63d;
--color-primary-hover: #498a29;
--color-primary-light: #96d675;
/* 强调色 */
--color-action: #d33216;
--color-action-hover: #a22611;
--color-action-light: #f39b8c;
/* 底色 */
--color-base: #12243b;
--color-base-light: #9dbbe1;
/* spaccing 间距 */
--section-padding-x: 3rem; /* Section的左右边距 */
--section-padding-y: 8rem; /* Section的上下边距 */
--button-radius: 1rem; /* 按钮的圆角 */
--card-radius: .5rem; /* 卡片的圆角 */
--card-padding: 1rem; /* 卡片的内边距 */
--gap: 2rem; /* 元素的间距 */
--content-gap: 2.5rem; /* 内容的间距 */
/* 字体大小 */
--font-size: 1.125rem;
--h1: 6rem;
--h2: 5rem;
--h3: 3.5rem;
--h4: 2.5rem;
--h5: 1.5rem;
--h6: 1.2rem;
}
所有在以后的设计搭建中会不断重复使用到的值我们都可以通过这样自定义属性来方便管理维护,同时也使你的设计具有延续性。经常看到人设置一个容器的上下边距的时候都是手动填入一个具体的数值60px,80px,这需要你一直记得这个数值,但是如果你要记得数值多了呢,一定会记错。更重要的是当你要修改调整这个数值时才是噩梦的开始。
但是细心的你也会发现这个基础款存在着问题和限制。
比如主色的悬停色 --color-primary-hover
,当你把主色颜色换成其他颜色时候,这个颜色你还是得手动到颜色生成的网站去找到它对应的更深或者更浅的一个色调填入进去。
比如section的边距我想设置不同断点(breakpoint)设置不同的大小,在平板下和手机下我都想设置分别不同的值,同样字体也是一样的问题。我们当然可以设置四个自定义属性用在在四个断点(breakpoint),但是有没有更好的办法呢?
答案是肯定的,下面我们看看一个进阶版本的设置:
:root {
/** colors 颜色体系 **/
/* 主色调 */
--color-primary: hsl(var(--color-primary-h) var(--color-primary-s) var(--color-primary-l));
--color-primary-hover: hsl(var(--color-primary-h) var(--color-primary-s) var(--color-primary-l) / 0.85);
--color-primary-light: hsl(var(--color-primary-h) var(--color-primary-s) var(--color-primary-l) / 0.2);
--color-primary-h: 265;
--color-primary-s: 83%;
--color-primary-l: 57%;
/* 强调色 */
--color-action: hsl(var(--color-action-h) var(--color-action-s) var(--color-action-l));
--color-action-hover: hsl(var(--color-action-h) var(--color-action-s) var(--color-action-l) / 0.85);
--color-action-light: hsl(var(--color-action-h) var(--color-action-s) var(--color-action-l) / 0.2);
--color-action-h: 31;
--color-action-s: 100%;
--color-action-l: 48%;
/* 底色 */
--color-base: hsl(var(--color-base-h) var(--color-base-s) var(--color-base-l));
--color-base-hover: hsl(var(--color-base-h) var(--color-base-s) var(--color-base-l) / 0.85);
--color-base-light: hsl(var(--color-base-h) var(--color-base-s) var(--color-base-l) / 0.2);
--color-base-h: 214;
--color-base-s: 97%;
--color-base-l: 27%;
/* spaccing 间距 */
--section-padding-x: clamp(4.6875rem, calc(4.6875rem + ((1vw - 0.2rem) * 5.7692)), 7.5rem); /* Section的左右边距 */
--section-padding-y: clamp(1.5rem, calc(1.5rem + ((1vw - 0.2rem) * 0.7692)), 1.875rem); /* Section的上下边距 */
--button-radius: 1rem; /* 按钮的圆角 */
--card-radius: .5rem; /* 卡片的圆角 */
--card-padding: 1rem; /* 卡片的内边距 */
--gap: 2rem; /* 元素的间距 */
--content-gap: 2.5rem; /* 内容的间距 */
/* 字体大小 */
--text-xs: clamp(0.79rem, -0.02vw + 0.79rem, 0.78rem);
--text-s: clamp(0.89rem, 0.1vw + 0.87rem, 0.94rem);
--text-m: clamp(1rem, 0.26vw + 0.95rem, 1.13rem);
--text-l: clamp(1.13rem, 0.46vw + 1.03rem, 1.35rem);
--text-xl: clamp(1.27rem, 0.73vw + 1.12rem, 1.62rem);
/* 标题大小 */
--h-6: clamp(0.8rem, -0.05vw + 0.81rem, 0.77rem);
--h-5: clamp(1rem, 0.06vw + 0.99rem, 1.03rem);
--h-4: clamp(1.25rem, 0.26vw + 1.2rem, 1.38rem);
--h-3: clamp(1.56rem, 0.55vw + 1.45rem, 1.83rem);
--h-2: clamp(1.95rem, 1.01vw + 1.75rem, 2.44rem);
--h-1: clamp(2.44rem, 1.67vw + 2.11rem, 3.26rem);
}
在颜色体系中你会发现有很多套娃一样的,这是怎么回事?
这里的颜色值我们没有再使用十六进制,而是采用了hsl的颜色格式。关于什么是十六进制什么是hsl格式我们这里就不展开说了,反正这两个都是可以用来显示颜色的格式。而hsl格式可以让我们更好的来创建和调整同一个颜色不同透明度,你看到的0.85就是这个颜色下85%不透明度下的颜色,0.2就是20%下的颜色。这也就意味着我们只要设置好h,s,l三个值,有需要的话我们还可以去定义他们更多的阴影色。
而在涉及到间距,字体里面,原来的px,rem数值变成了clamp很长一段,这又是怎么回事?
在这里,我们是为了解决上面提到的在不同断点下显示不同的数值大小引入了clamp()函数,而我们只需要一个自定义属性就能实现这个效果。同时你也不用在编辑器里面找到四个breakpoint断点去分别设置四次了,这里涉及到的Fluid Responsive Development流体响应式开发我们会下一章详细介绍。你只需要知道它实现的效果远比在每一个断点手动设置大小来的强大和带来更好的体验。
如何将自定义设置使用到bricks builder中
问题来了,这些自定义的代码我们怎么样在bricks builder中使用呢?
通常我会把这些全局变量放在bricks的子主题里面,你只要打开appearance外观 – theme file editor主题编辑器,右上角确认当前选择的是bricks child theme子主题,选择stylesheet。在这里创建你的全局自定义属性,保存之后这些属性在整个网站都可以调用使用了,在后面的文章中我也会演示在编辑器面如何调用这些属性。
使用Core Framework免费版本来创建你自己的CSS框架
没错,Core Framework其实有一个免费的在线版本可以让用户自己创建一个自己的CSS框架,感谢群友大佬款风速想提供的有用信息。
你只要注册一个core framework账号就能使用他在线的web app。
这个web app有和bricks版本一样的功能设置,你可以根据你自己的需求去定制变量的名字,不需要的可以删除。
最后可以preview CSS,把你需要的这些复制到子主题的样式表里面使用。CSS也是一个很优秀的CSS框架,他的自定义程度很高。如果你觉得他不错,他也有bricks builder付费版本。
Automatic CSS – WordPress的CSS框架
那么,有没有这样一款工具,他给你设置好了这些东西,你要做的就是找到它的预设值,引入到你的网站里面去。答案是肯定的,Automatic CSS 简称ACSS,具体关于这个工具的介绍可以看我的这篇文章- Automatic CSS – 一款为WordPress开发的CSS框架。简单的说这是一个给bricks builder, oxygen开发的预设css框架,上面提到的这些自定义属性都包含在里面,但是他能给你的设置选项远比这更多,我自己本身大部分的网站都有用这个工具来更方便的开发。
关于ACSS更多功能的我也会在后面的文章中来介绍,优秀的工具希望能让更多英文不是那么好的同胞了解。
资料参考
写这篇文章参考了如下一些博主的文章,十分感谢。
CSS 变量教程:https://www.ruanyifeng.com/blog/2017/05/css-variables.html
CSS 变量的定义——什么是 CSS 变量以及如何使用它们?:https://www.freecodecamp.org/chinese/news/what-are-css-variables-and-how-to-use-them/
CSS 自定义属性/变量 (variables):https://zhuanlan.zhihu.com/p/613058216
CSS 变量使用详解:https://www.jianshu.com/p/cd583e30719d
CSS局部变量:http://cdn1.w3cplus.com/css/local-css-vars.html
CSS Variables with Global & Local Scope:https://dev.to/swarnaliroy94/css-variables-with-global-local-scope-4gbf