CSS揭秘

CSS编码技巧

尽量减少代码重复

代码可维护性的最大要素是尽量减少改动时要编辑的地方

比如,当我们需要改变一个按钮的字号,就得同时调整行高。而行高并没有反映出它跟字号的关系,因此我们通常需要算出字号改变之后的行高是多少。所以,当某些值相互依赖时,应该把他们相互关系用代码表达出来

font-size: 20px;

line-height: 1.5;

代码易维护 vs 代码量少

给一个元素添加一条10px的边框,但左侧不加边框

border-width: 10px 10px 10px 0;

或者:

border-width: 10px;

border-left-width: 0;

相比之下,第二条显然可读性更好,且更容易维护

CSS中有史以来的第一个变量

currentColor

没错,其实很多已有属性都具有类似的行为。比如,你没有给边框指定颜色,他就会自动的从文本颜色哪里得到颜色。

继承

说到继承,大家都很熟悉却很少用到它。

input, select, button {

    font: inherit;

}

其实,在我们做提示框的小箭头啊使用伪类的时候非常有用:

.arrow-wrap {

    position: relative;

}

.arrow-wrap::before {

    content: '';

    position: absolute;

    top: 0;

    left: 0;

    background: inherit;

    border: inherit;

}

这样,提示框的小箭头从父元素那里获取了背景色和边框样式

预处理器也不是完美无缺的

Stylus、Sass、Less都是常用的CSS预处理器

  • CSS文件体积和复杂度失控:在代码编译后很可能出现一些未知的问题

  • 调试难度增加:控制台看见的并不是你写的源码

  • 延时:通常需要一秒的时间把源码翻译成CSS

  • 它们有它们自己的bug:因为预处理器也是人写的,也会有bug

原声特性通常比预处理器提供的版本要强大的多,因为他们是动态的(可以通过脚本操纵CSS)

比如,预处理器不知如何完成100% - 50px这样的计算,因为在页面真正被渲染之前,百分比值是无法解析的。而原生CSS的calc()在计算这样的表达式时没有任何压力。

背景与边框

半透明边框

在进入主题之前,我发现自己对于color这个属性其实了解的很少。通常描述颜色只会用到关键字red,或十六进制的rgb#ffffff,实际上颜色可以有以下几种表示方法:

  • 使用一个关键字red

  • 使用RGB立体坐标系统,以#加十六进制或rgb()rgba()函数表达式的形式(红绿蓝+透明度)

  • 使用HSL圆柱坐标系统,以hsl()hsla()函数表达式的形式(色相饱和度明度 + 透明度)

实现一个半透明边框

我们通常这样写:

border: 10px solid hsla(0,0%,100%,.5)

background: white;

实际上,上面代码中背景会将这个半透明边框完全覆盖

隆重介绍一下这个属性background-clip,这个属性的初始值是border-box,意味着背景会被元素的border-box裁掉。如果不希望背景侵入边框所在范围,需要把值设置为padding-box,使用内边距外沿裁切背景。

border: 10px solid hsla(0,0%,100%,.5)

background: white;

background-clip: padding-box;

上面代码完美实现了半透明边框

多重边框

box-shadow 方案

我们通常使用box-shadow实现阴影,不为人知的是,它接受第四个参数,扩张半径。通过指定正值或负值可以让投影面积加大或者减小。

background: yellowgreen;

box-shadow: 0 0 0 10px #655;

上面代码实现了一个宽度为10的实线边框,border属性完全可以实现同样的效果,但是box-shadow牛批的地方在于它支持逗号分隔语法,我们可以创建任意数量的投影。比如在这个实线边框外再加一个边框:

border: yellowgreen;

box-shadow: 0 0 0 10px #655,

            0 0 0 15px deeppink;

但是,这个实线边框(扩张阴影)是逐层叠加的,所以实际上这个deeppink的边框我们能看到的宽度是5px(15px - 10px = 5px)。

甚至你可以继续累加阴影效果:

border: yellowgreen;

box-shadow: 0 0 0 10px #655,

            0 0 0 15px deeppink,

            0 2px 5px 15px rgba(0,0,0,.6);

需要注意的是:投影行为和边框不完全一致,因为它不会影响布局,也不会受到box-sizing影响。另一点是,它只是一个阴影,所以也不会影响鼠标事件

outline 方案

某些情况,如果只需要两层边框,就可以先设置一层常规边框,再加上outline(描边)。这种方法的一大优点在于边框样式十分灵活(虚线),而box-shadow方案只能模拟实线边框。

实现上面效果可以这样写:

background: yellowgreen;

border: 10px solid #655;

outline: 5px solid deeppink;

局限:只适用于双层边框

灵活的背景定位

background-position 的扩展语法方案

background-origin 方案

以上两种方案了解掌握,目前项目中背景图片的使用场景很少。通常是对元素的绝对定位。

calc()方案

calc()函数在项目中使用频率比较高,通常用来计算一些动态的长度。比如给一个页面的header固定高度,计算内容部分的值就可以用到calc()

header{

    height: 100px;

}

main {

    height: calc(100% - 100px)

}

不要忘记在calc()函数内部的-运算符两侧各加一个空白符,否则会产生解析错误。

边框内圆角

场景:我们需要一个容器,只在内侧有圆角,而边框或描边的四个角在外部仍然保持直角的形状

image.png

通常这么写:

I have a nice subtle inner rounding, don’t I look pretty?
.wrap { background: #655; padding: .8em; } .wrap > div { background: tan; border-radius: .8em; padding: 1em; }

这样写没什么毛病,就是需要使用两个元素

如果只用一个元素实现,那么这样写:

background: tan;

border-radius: .8em;

padding: 1em;

box-shadow: 0 0 0 .6em #655;

outline: .6em solid #655;

这种写法得益于两个事实:

1、描边并不会跟着圆角走(因此显示出直角)

2、box-shadow会跟着圆角走(实线的圆角边框)

因此,这两个条件叠加在一起达到了我们想要的效果

box-shadow指定的扩张至不一定要和描边宽度相同,只要是满足空缺的宽度即可

条纹背景

前置知识:linear-gradient 函数用于创建一个表示两种或多种颜色线性渐变的图片

场景:假设我们有一条基本的垂直线性渐变,颜色从#fb3过渡到#58a

background: linear-gradient(#fb3, #58a)
image.png

当我们给这两个颜色一个区域比方说,就会变成这样:

background: linear-gradient(#fb3 50%, #58a 50%)
image.png

看起来完全不渐变了呢,那是因为如果多个色标具有相同的占比,它们会产生一个无限小的过滤区域,从效果上看,颜色会突然变化,而不是一个平滑渐变的过程。就像两块实色各占据一半的面积。

结合background-size就可以创建条纹背景啦,因为背景在默认情况下是重复平铺的

background: linear-gradient(#fb3 50%, #58a 50%);

background-size: 100% 100px;

垂直条纹

垂直条纹的代码跟水平条纹几乎是一样的,差别主要在于:我们需要在开头加上一个额外参数来指定渐变方向。最后再把background-size的值颠倒一下:

background: linear-gradient(to right, #fb3 50%, #58a 50%);

background-size: 100px 100%;

斜向条纹

repeating-linear-gradient()repeating-radial-gradient()

形状

自适应的椭圆

重新认识border-radius,它有一个鲜为人知的真相,单独指定水平和垂直半径,用一个/分隔这两个值。我们可以利用这个特性创建椭圆:

border-radius: 100px / 75px;

但是,这段代码存在一个很大的缺陷,只要元素尺寸发生变化,border-radius的值就会跟着改变。

所以,border-radius最好使用百分比值。这个百分比值会基于元素尺寸进行解析,即宽度用于水平半径解析,而高度用于垂直半径的解析。

border-radius: 50%;

持续更新。。。

你可能感兴趣的:(CSS揭秘)