css实战小技巧

这次我们来看下几个css简洁优雅的的使用技巧,特此声明,这里说的 CSS 并不止包含 CSS,也包含 CSS 预处理器(Less Sass 等),愿各位看官不要纠结于此。

尽量使用 padding 代替 margin

paddingmargin 两个是常用的属性,但是属于同一个 BFC 的两个相邻 Box 的 margin 会发生重叠,所以如果 margin 使用的过于频繁的时候,Box 的垂直距离可能就会发生重叠。第一个子元素的 margin-top 值会加在父元素上的 bug,最后一个子元素的 margin-bottom 也存在类似的问题。

​ 原因:所有毗邻的两个或多个盒元素的 margin 将会合并为一个 margin 共享。所以我们可以在首位元素使用 padding 来替代 margin。当然有的时候使用 padding 不能满足需求,这时你也可以在“非空内容”这个条件做文章。即在父元素添加一个伪元素。

position:fixed 降级问题

​ 开发中遇到的“吸顶”问题,就是position:fixed 这个属性。如果父元素有使用transform,fixed 的效果会降级为 absolute

解决方案

​ 既然会降级为 absolute 效果,我们该怎么解决这个问题呢?我们就改考虑什么情况下 fixedabsolute 的表现效果会是一样的。即当使用 fixed 的直接父元素的高度和屏幕的高度相同时 fixedabsolute 的表现效果会是一样的。如果这个直接父级内的元素存在滚动的情况,那就加上 overflow-y:auto

合理使用 px | em | rem | % 等单位

​ 在 CSS 中有许多距离单位,比如 px | em | rem | %,还有 CSS3 中的 vh | vw 等单位。px是pc端最常用的单位,但是再移动端自适应的要求下,使用的场景就不是很多了,以下几种小的适用场景。

比较小的图案

​ 比如画一个 r 为 5px 的圆,如果我们使用 rem 作为单位,我们很快会发现在一些机型上的图案不圆,会呈现椭圆形。这是由于 rem 转 px 会存在精度丢失问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// less 
//使用 px 配合 dpr 来实现:
/*@size 建议取双数*/
.circle(@size,@backgroundColor){
width:@size;
height:@size;
background-color:@backgroundColor;
[data-dpr="1"] & {
width: @size * 0.5;
height: @size * 0.5;
}
[data-dpr="3"] & {
width: @size * 1.5;
height: @size * 1.5;
}
}

字体大小

​ 移动端,一般情况字体的大小会使用 rem 作为单位,它 是 CSS3 新增的一个相对单位(root em),即相对 HTML 根元素的字体大小的值; em 也是一个相对单位,却是相对当前元素的字体大小。line-height建议使用使用 em,因为在需要调整字体大小的时候,只需修改 font-size 的值,而 line-height 已经设置成了相对行高了。首行缩进两个字符,也适合使用em这个单位

1
text-indent: 2em

视口单位 vw | vh

vw: 1vw = 视口宽度的 1%
vh: 1vh = 视口高度的 1%

​ 视口单位 vw | vh,可以用来解决rem单位设计弹性布局,需要再头部加载一段脚本来监听分辨率变化,动态改变根元素字体的大小,css与js耦合的问题。

上大佬们代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// rem 单位换算:定为 75px 只是方便运算,750px-75px、640-64px、1080px-108px,如此类推
$vm_fontsize:75;
@function rem($px){
@return ($px / $vm_fontsize) * 1rem;
}
// vm
$vm_design:750;
html{
font-size:($vm_fontsize / ($vm_design / 2)) * 100vm; //rem 的值用 vm表示,后面就可以使用rem了
@media screen and (max-width: 320px) {
font-size: 64px;
}
@media screen and (min-width: 540px) {
font-size: 108px;
}
}
// body 也增加最大最小宽度限制,避免默认100%宽度的 block 元素跟随 body 而过大过小
body {
max-width: 540px;
min-width: 320px;
}

1px 细线问题

​ 处理 1px 细线问题是移动端需求必不可免的,目前没有什么兼容性特别好的方案,这里我只是提供两种种相对较好的方案。

使用伪类 + transform

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
.border_bottom{
overflow: hidden;
position: relative;
border: none !important;
}
.border_bottom:after{
content: '.';
position: absolute;
left: 0;
bottom: 0;
width: 100%;
height: 1px;
background-color: #d4d6d7;
-webkit-transform-origin: 0 0;
transform-origin: 0 0;
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
}

当然这个方案在一些版本较低的机型也是会出现粗细不均、细线消失断裂的兼容性问题。

使用 box-shadow 模拟

1
2
3
4
.border_bottom {
box-shadow: inset 0px -1px 1px -1px #d4d6d7;
}
/* 本可以满足所有场景,不过有个缺点也就是颜色会变浅。*/

从 html 元素继承 box-sizing

​ 在设置元素的 borderpadding 并不希望改变元素的 width,height值,就可以为该元素设置 box-sizing:border-box;。如果不希望每次都重写一遍,可以继承来实现。

1
2
3
4
5
6
7
8
html {
box-sizing: border-box;
}

*, *:before, *:after {
box-sizing: inherit;
}
/*不会覆盖其他组件的 box-sizing 值,又无需为每一个元素重复设置 box-sizing:border-box;*/

内联首屏关键 CSS

​ 性能优化中有一个重要的指标 —— 首次有效绘制(FMP),即指页面的首要内容(primary content)出现在屏幕上的时间。这一指标影响用户看到页面前所需等待的时间,而 内联首屏关键 CSS(即 Critical CSS,可以称之为首屏关键 CSS) 能给用户一个更好的心理预期。内联 CSS 能够使浏览器开始页面渲染的时间提前,即在 HTML 下载完成之后就能渲染,我们可以将首屏的css内联再html中。

文字超出省略、文字两端对齐

超出省略

1
2
3
4
5
6
7
8
.line-camp( @clamp:2) {
text-overflow: -o-ellipsis-lastline;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: @clamp;
-webkit-box-orient: vertical;
}

两端对齐

1
2
3
4
5
<!-- html -->
<div>姓名</div>
<div>手机号码</div>
<div>账号</div>
<div>密码</div>
1
2
3
4
5
6
div {
margin: 10px 0;
width: 100px;
border: 1px solid red;
text-align-last: justify;
}
-------------本文结束感谢您的阅读-------------