CSS 编码技巧和Emmet 语法介绍
文章目录
CSS 编码技巧
DRY 全称:Don’t Repeat Yourself (摘自wikipedia),是指编程过程中不写重复代码,将能够公共的部分抽象出来,封装成工具类或者用“abstraction”类来抽象公有的东西,降低代码的耦合性,这样不仅提高代码的灵活性、健壮性以及可读性,也方便后期的维护或者修改。
尽量减少代码重复
在软件开发中,保持代码的 DRY 和可维护性是最大的挑战之一,而这句话对 CSS 也是适用的。在实践中,代码可维护性的最大要素是尽量减少改动时要编辑的地方。
例如:放大一个按钮时需要多处css规则(字体,行高等),那就很可能会漏改其中某处,后期维护也会比较困难。
灵活的 CSS 通常更容易扩展:在写出基础样式之后,只用极少的代码就可以扩展出不同的变体,因为只需覆盖一些变量就可以了。
让我们来看一个例子。
最初的button
padding: 6px 16px;
border: 1px solid #446d88;
background: #58a linear-gradient(#77a0bb, #58a);
border-radius: 4px;
box-shadow: 0 1px 5px gray;
color: white;
text-shadow: 0 -1px 1px #335166;
font-size: 20px;
line-height: 30px;
如果我们决定改变字号(可能是为了生成一个更大、更重要的按钮),就得同时调整行高,因为这两个属性都写成了绝对值。
当某些值相互依赖时,应该把它们的相互关系用代码表达出来。
将行高和字体进行关联
改成 :行高是字号的 1.5 倍
font-size: 20px;
line-height: 1.5;
如果我们决定把父级的字号加大,就不得不修改每一处使用绝对值作为字体尺寸的样式。
字体改成相对父级的大小
font-size: 125%; /* 假设父级的字号是 16px */
line-height: 1.5;
其他的效果改成em单位
如果我们改变父级的字号,按钮的尺寸就会随之变化。但是,它看起来很不协调只放大字体会破坏按钮的其他效果(最突兀的就是圆角),因为它们都被指定了一些绝对的长度值。如果我们把这些长度值都改成 em 单位,那这些效果的值就都变成可缩放的了,而且是依赖字号进行缩放。
padding: .3em .8em;
border: 1px solid #446d88;
background: #58a linear-gradient(#77a0bb, #58a);
border-radius: .2em;
box-shadow: 0 .05em .25em gray;
color: white;
text-shadow: 0 -.05em .05em #335166;
font-size: 125%;
line-height: 1.5;
注意:
还有一些长度值是绝对值。此时就需要重新审视到底哪些效果应该跟着按钮一起放大,而哪些效果是保持不变的。
eg:按钮的边框粗为 1px,不受按钮尺寸的影响。
颜色改变
假设我们要创建一个红色的取消按钮,或者一个绿色的确定按钮,该怎么做呢?
有一下3个问题要考虑
- 多处颜色修改:我们可能需要覆盖四条声明(
border-color、background、box-shadow 和 text-shadow
) - 按钮亮暗面:要根据按钮的亮面和暗面相对于主色调 #58a 变亮和变暗的程度来分别推导出其他颜色各自的亮色和暗色版本。
- 投影颜色:把按钮放在一个非白色的背景之上时,使用灰色( gray)作投影只适用于纯白背景的情况。
解决方案:
把半透明的黑色或白色叠加在主色调上,即可产生主色调的亮色和暗色变体,这样就能简单地化解这些问题了;
padding: .3em .8em;
border: 1px solid rgba(0,0,0,.1);
background: #58a linear-gradient(hsla(0,0%,100%,.2),
transparent);
border-radius: .2em;
box-shadow: 0 .05em .25em rgba(0,0,0,.5);
color: white;
text-shadow: 0 -.05em .05em rgba(0,0,0,.5);
font-size: 125%;
line-height: 1.5;
现在我们只要覆盖 background-color 属性,就可以得到不同颜色版本的按钮了
button.cancel {
background-color: #c00; }
button.ok {
background-color: #6b0; }
1. 代码易维护 vs. 代码量少
有时候,代码易维护和代码量少不可兼得。
例如:我们要为一个元素添加一道 10px 宽的边框,但左侧不加边框。
border-width: 10px 10px 10px 0;
如果把它拆成两条声明的话,改起来就容易多了,而且可读性或许更好一些:
border-width: 10px;
border-left-width: 0;
2. currentColor
currentColor 关键字代表原始的 color 属性的计算值。它允许让继承自属性或子元素的属性颜色属性以默认值不再继承。
它也能用于那些继承了元素的 color 属性计算值的属性,相当于在这些元素上使用 inherit 关键字,如果这些元素有该关键字的话。
https://developer.mozilla.org/zh-CN/docs/Web/CSS/color_value
例如:假设我们想让所有的水平分割线(所有 <hr>
元素)自动与文本的颜色保持一致。有了 currentColor 之后,我们只需要这样写:
hr {
height: .5em;
background: currentColor; }
3. 继承
尽管绝大多数开发者都知道有 inherit 这个关键字,但还是很容易遗忘它。
inherit 可以用在任何 CSS 属性中,而且它总是绑定到父元素的计算值(对伪元素来说,则会取生成该伪元素的宿主元素)。
例如:要把表单元素的字体设定为与页面的其他部分相同,你并不需要重复指定字体属
性,只需利用 inherit 的特性即可;
input, select, button { font: inherit; }
例如:要把超链接的颜色设定为与页面中其他文本相同,还是要用inherit:
a { color: inherit; }
例如:在创建提示框的时候,你可能希望它的小箭头能够自动继承背景和边框的样式
.callout { position: relative; }
.callout::before {
content: "";
position: absolute;
top: -.4em; left: 1em;
padding: .35em;
background: inherit;
border: inherit;
border-right: 0;
border-bottom: 0;
transform: rotate(45deg);
}
Emmet
引入问题
如何快速编写以下代码?
<div>
<span>
<ul id="nav">
<li class="item">
<a href="">Item 1</a>
<div class="1"></div>
</li>
<li class="item">
<a href="">Item 2</a>
<div class="2"></div>
</li>
<li class="item">
<a href="">Item 3</a>
<div class="3"></div>
</li>
<li class="item">
<a href="">Item 4</a>
<div class="4"></div>
</li>
</ul>
</span>
</div>
如果需要你写以上代码,您会怎么写,是一个字母一个字母地硬打出来吗?
在不了解emmet语法的时候可能会写出一个li
结构,然后再copy+copy,你以为这就很快了吗?如果使用emmet可以让你快到起飞。
接下来我们演示一下使用emmet
可以几秒写好这段代码
div>span>ul#nav>li.item*4>a{Item $}+.$
Emmet介绍
在前端开发的过程中,最费时间的工作就是写 HTML、CSS 代码。一堆的标签、属性、括号等,头疼。
Emmet语法可以用缩写 来动态生成我们所需要生成出我们所需要的样式,在短时间做出来一个模板,然后使用,这是一个能够大幅度提高效率的工具,下面介绍下基本语法。
Emmet是一款插件,只要能安装他的编辑器都能使用,大部分编辑器都可以使用该语法规则,我们平时开发的Sublime Text、Eclipse、Notepad++、VS code、Atom、Dreamweaver等等编辑器都可以使用。
Emmet的HTML基本用法
- 生成HTML文档初始机构
html:5
或者!
生成 HTML5 结构
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
</body>
</html>
-
任意一个 html 标签输入都会生成完整的闭合标签。
例如输入p
按 tab 则 生成:<p></p>
-
生成带有 id 、class 的 HTML 标签:
#
为 id,.
为 class。
例如输入div#header.section
则生成<div id="header" class="section"></div>
-
生成后代:
>
例如输入p>span
则生成<p><span></span></p>
-
生成兄弟标签:
+
例如输入p+div
则生成<p></p><div></div>
-
生成上级标签:
^
例如输入ul>li>a^div
则生成
<ul>
<li><a href=""></a></li>
<div></div>
</ul>
- 也可以使用多个
^
,
例如输入ul>li>a^^div
则生成
<ul>
<li><a href=""></a></li>
</ul>
<div></div>
- 重复生成多个标签
*
例如输入ul>li*5
则生成
<ul>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
- 生成分组的标签:
()
例如输入ul>(li>a)*5
则生成
<ul>
<li><a href=""></a></li>
<li><a href=""></a></li>
<li><a href=""></a></li>
<li><a href=""></a></li>
<li><a href=""></a></li>
</ul>
注意和ul>li>a*5
生成是不一样的
<ul>
<li>
<a href=""></a>
<a href=""></a>
<a href=""></a>
<a href=""></a>
<a href=""></a>
</li>
</ul>
- 生成自定义属性:
[]
例如输入img[https://octodex.github.com/images/codercat.jpg][alt=octcat]
则生成
<img src="https://octodex.github.com/images/codercat.jpg" alt="octcat" />
- 生成递增的属性标签等:
$
例如输入ul>li.item$*5
则生成
<ul>
<li class="item1"></li>
<li class="item2"></li>
<li class="item3"></li>
<li class="item4"></li>
<li class="item5"></li>
</ul>
- 生成多位递增的呢:
$$$
例如输入ul>li.item$$$*5
则生成
<ul>
<li class="item001"></li>
<li class="item002"></li>
<li class="item003"></li>
<li class="item004"></li>
<li class="item005"></li>
</ul>
想生成几位输入几个$
- 要生成递减的呢:
@-
例如输入ul>li.item$@-*5
则生成
<ul>
<li class="item5"></li>
<li class="item4"></li>
<li class="item3"></li>
<li class="item2"></li>
<li class="item1"></li>
</ul>
- 想要从某个特定的顺序开始呢:
@N
例如输入ul>li.item$@10*5
则生成
<ul>
<li class="item10"></li>
<li class="item11"></li>
<li class="item12"></li>
<li class="item13"></li>
<li class="item14"></li>
</ul>
- 逆序生成到某个数:
@-
例如输入ul>li.item$@-10*5
则生成
<ul>
<li class="item14"></li>
<li class="item13"></li>
<li class="item12"></li>
<li class="item11"></li>
<li class="item10"></li>
</ul>
- 生成文本内容:
{}
例如输入p{我是paddingme}
则生成
<p>我是paddingme</p>
- 缺省元素:
声明一个带class的div 可以不用输入div;
.header+.footer
则生成:
<div class="header"></div>
<div class="footer"></div>
- Emmet 还会根据父标签进行判定
例如输入ul>.item*3
则生成:
<ul>
<li class="item"></li>
<li class="item"></li>
<li class="item"></li>
</ul>
例如select>.test$*5
<select name="" id="">
<option class="test1"></option>
<option class="test2"></option>
<option class="test3"></option>
<option class="test4"></option>
<option class="test5"></option>
</select>
下面是所有的隐式标签名称:
li:用于 ul 和 ol 中
tr:用于 table、tbody、thead 和 tfoot 中
td:用于 tr 中
option:用于 select 和 optgroup 中
Emmet的CSS基本用法
h200 => height:200px;
w10 => width:10px;
m10-20 => margin:10px 20px;
b20p => bottom:20%;
bd => border: 1px solid #000;
tac => text-align: center;
fz16 => font-size: 16px;
fwb => font-weight: bold;
小结
Emmet语法,主要分为三个部分,嵌套运算符(Nesting Operator)、属性操作符(Attribute Operators)、隐式标签(Implicit label)。
类别 | 操作符名称 符号 | 符号 | 用法 |
---|---|---|---|
嵌套运算符 | 子代操作符 | > | div>div>span |
嵌套运算符 | 兄弟操作符 | + | div>div+span |
嵌套运算符 | 返回上级操作符 | ^ | div>div+span^div |
嵌套运算符 | 乘法操作符 | * | div>div*5 |
嵌套运算符 | 分组操作符 | () | (header>h1+div>p)+(div>p)+(footer>ul>li*3) |
属性操作符 | ID和Class | . # | div#id>div.class |
属性操作符 | 定制属性 | [] | div[a="a",b="b"] |
属性操作符 | 数值计算操作符 | $ $@- $@N | div.item-$*3 div.item-$@-*3 |
属性操作符 | 文本操作符 | {} | div*3{测试$$} |
隐式标签 | li tr td option 等 | .class |