web前端开发技术博客
当前位置: HTML/CSS > 9.9 个 CSS 小技巧 让你有更多时间摸鱼

9.9 个 CSS 小技巧 让你有更多时间摸鱼

2019-05-17 分类:HTML/CSS 作者:码云 阅读(6401)

作者:小生方勤(本文来自作者投稿)

前言

在这篇文章我会介绍9个使你的CSS更加简洁优雅的使用技巧。这些技巧小生经常使用,觉得挺高效实用,所以也就有了这篇文章。

9个CSS技巧

特此声明,这里说的CSS并不止包含CSS,也包含CSS预处理器(Less Sass等),愿各位看官不要纠结于此。

正文现在开始。

1.尽量使用padding代替margin

我们在设计稿还原的时候,padding和margin两个是常用的属性,但我们知道属于同一个BFC的两个相邻Box的margin会发生重叠,所以如果margin使用的过于频繁的时候,Box的垂直距离可能就会发生重叠。

还有一个问题就是第一个子元素的margin-top值会加在父元素上的bug(最后一个子元素的margin-bottom也存在类似的问题)。这里是不是有人问为什么呢?

原因就在于:

1
the expression collapsing margins means that adjoining margins (no non-empty content, padding or border areas or clearance separate them) of two or more boxes (which may be next to one another or nested) combine to form a single margin.

翻译过来就是:

所有毗邻的两个或多个盒元素的margin将会合并为一个margin共享。毗邻的定义为:同级或者嵌套的盒元素,并且它们之间没有非空内容、Padding或Border分隔。

至于为什么合并我个人觉得这和排队取款的安全距离有点类似,人与人之间的安全距离是1m,如果安全距离不合并,那么我们在排队的时候是不是人与人的距离就变成2m了。当然很可能不是这个原因。

所以我们可以在首位元素使用padding来替代margin。当然有的时候使用padding不能满足需求,这时你也可以在“非空内容”这个条件做文章。即在父元素添加一个伪元素。

所以我们在使用margin的时候一定要注意collapsing margins问题。

2.position:fixed降级问题

不知道曾经的你是不是遇到吸顶效果,就是使用position:fixed这个属性。其实如果其父元素中有使用transform,fixed的效果会降级为absolute。

解决方案:

既然会降级为absolute效果,我们该怎么解决这个问题呢?我们就改考虑什么情况下fixed和absolute的表现效果会是一样的。

即当使用fixed的直接父元素的高度和屏幕的高度相同时fixed和absolute的表现效果会是一样的。

如果这个直接父级内的元素存在滚动的情况,那就加上 overflow-y:auto。

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

在CSS中有许多距离单位,比如px|em|rem|%,还有CSS3中的vh|vw等单位。

那么我们在项目中应该如何使用呢?我们在pc端不需要考虑的这么复杂,所以这里我们主要讲讲这些单位在移动端中的使用。亲看我之前的一篇文章《视口百分比长度vh、vw、vi、vb、vmin、vmax单位的了解

基础单位px

px是我们最早接触到的单位了,不过我们在移动端自适应的要求下,使用的频率不是很高;我总结了以下使用的情况:

比较小的图案

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

所以这个时候我们就需要使用px配合dpr来实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// less
/*@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;
    }
}

1px细线问题

这个问题下面我会单独做一小节讲,在这里就不累述。

字体大小(基本都是用rem作为单位)

一般情况字体的大小我也会使用rem作为单位,因为精度丢失我认为在可以接受的范围之内。

相对单位rem

rem是CSS3新增的一个相对单位(root em),即相对HTML根元素的字体大小的值。

rem应该是自适应使用的最广泛的单位了。

相对单位em

em也是一个相对单位,却是相对当前元素的字体大小。

line-height

一般建议在line-height使用em。因为在需要调整字体大小的时候,只需修改font-size的值,而line-height已经设置成了相对行高了。

首行缩进两个字符

在存在首行缩进的需求,我也会使用这个单位。

1
text-indent: 2em

视口单位 vw | vh

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

我们知道以rem单位设计的弹性布局,是需要在头部加载一段脚本来进行监听分辨率的变化来动态改变根元素字体大小,使得CSS与JS耦合了在一起。

那么有没有方案解决这个耦合的问题呢?

答案就是视口单位 vw | vh。

以下就是前人给出的使用方案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$vm_fontsize: 75;
@function rem($px) {
     @return ($px / $vm_fontsize ) * 1rem;
}
$vm_design: 750;
html {
    font-size: ($vm_fontsize / ($vm_design / 2)) * 100vw;
    @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;
}

4.合理使用变量

一般设计稿中的某一类的文字(元素)都是用相同的字体大小、颜色、行高等样式属性,所以这些值我们不必每次都重复写,因为当UI更新设计方案,你需要改的地方就很多了。这些重复使用的值我们完全可以存放在变量里面。

Sass和Less稍微有点区别:

1
2
3
4
//sass
$direction:left;
//less
 direction:left;

当然 CSS 原生也是存在变量的,使用规则如下:

  • 变量定义的语法是:--;//*为变量名称。
  • 变量使用的语法是:var();

1、无论是变量的定义和使用只能在声明块{}里面

2、CSS变量字符限制为:[0-9]、[a-zA-Z]、_、-、中文和韩文等。

1
2
3
4
5
6
7
8
9
10
11
:root {
    --blue_color: #3388ff;
    --main_bgcolor: #fafafa;
    --font_size_12: 12px;
    --font_size_14: 14px;
    --color: 20px;
}
.div1{
    background-color: var(--main_bgcolor);
    font-size: var(--font_size_12);
}

5.使用Mixin归类重复样式

和重复变量一样,重复的样式也可以归类。我觉得优秀的代码其中有一条肯定是代码的复用性强。

之前我们写CSS的时候,也会将一些重复使用的代码放在一个class中,这样的确达到了一定的复用性,不过最后的效果可能就是在一个元素里面放了很多class,如下图:

9.9 个 CSS 小技巧 让你有更多时间摸鱼

这样下一个接手得人难免会有点迷糊,而且这样会造成样式越来越难修改。

这个时候,mixin(可以理解成class中的class)就能发挥它的作用了。

这是一个描述性文字的样式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
.font-description {
    .font-des-style(24px,#fff,1.5em);
    .line-camp(2);
}
// less示 */
.line-cam
/* 多行显p( @clamp:2 ) {
    text-overflow: -o-ellipsis-lastline;
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: @clamp;
    -webkit-box-orient: vertical;
}
.font-des-style( @fontSize, @color, @lineHeight, @textAlign:left ) {
    font-size: @fontSize;
    color: @color;
    line-height: @lineHeight;
    text-align: @textAlign;
}

这只是一个简单的例子,我们可以把可复用的样式放在mixin中,这样接手项目的人只需要熟悉你写的mixin.less就可以开始迭代需求了。

6.1px方案

做过移动端需求的前端肯定是避免不了处理1px细线问题,这个问题的原因就是UI对页面美观度的要求越来越高(不要和我说这是retina屏的问题)。

据小生所知好像没有什么兼容性特别好的方案,这里我只是提供两种种相对较好的方案。

使用伪类+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);
}

当然这个方案在一些版本较低的机型也是会出现粗细不均、细线消失断裂的兼容性问题。不过现在在已经2019年了,版本较低的机型也淘汰的差不多了。

使用box-shadow模拟

1
2
3
.border_bottom {
  box-shadow: inset 0px -1px 1px -1px #d4d6d7;
}

这个方案基本可以满足所有场景,不过有个缺点也就是颜色会变浅。

7.从html元素继承box-sizing

在大多数情况下我们在设置元素的border和padding并不希望改变元素的width,height值,这个时候我们就可以为该元素设置box-sizing:border-box;。

我不希望每次都重写一遍,而是希望他是继承而来的,那么我们可以使用如下代码:

1
2
3
4
5
6
html {
  box-sizing: border-box;
}
*, *:before, *:after {
  box-sizing: inherit;
}

这样的好处在于他不会覆盖其他组件的box-sizing值,又无需为每一个元素重复设置box-sizing:border-box;。

8.内联首屏关键CSS

性能优化中有一个重要的指标——首次有效绘制(FMP),即指页面的首要内容(primary content)出现在屏幕上的时间。这一指标影响用户看到页面前所需等待的时间,而内联首屏关键CSS(即Critical CSS,可以称之为首屏关键CSS)能给用户一个更好的心理预期。

如图:

内联首屏关键 CSS

我们知道内联CSS能够使浏览器开始页面渲染的时间提前,即在HTML下载完成之后就能渲染了。

既然是内联关键CSS,也就说明我们只会将少部分的CSS代码直接写入HTML中。至于内联哪些CSS你可以使用Critical。

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

需求中我们也经常遇到这样的需求,这里直接提供方案。

超出省略

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;
}

所遇到的问题:

-webkit-box-orient:vertical在使用webpack打包的时候这段代码会被删除掉,原因是optimize-css-assets-webpack-plugin这个插件的问题。

解决方案:

可以使用如下的写法:

1
2
3
4
5
6
7
8
9
10
.line-camp( @clamp:2 ) {
    text-overflow: -o-ellipsis-lastline;
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: @clamp;
    /*! autoprefixer: off */
    -webkit-box-orient: vertical;
    /* autoprefixer: on */
}
optimize-css-assets-webpack-plugin

两端对齐

1
2
3
4
5
6
7
8
9
10
11
12
// html
<div>姓名</div>
<div>手机号码</div>
<div>账号</div>
<div>密码</div>
// css
div {
    margin: 10px 0;
    width: 100px;
    border: 1px solid red;
    text-align-last: justify;
}

效果如下:

两端对齐

【本文作者】

小生方勤:「前端词典」系列文章作者,致力于输出对读者有帮助的文章

「如果觉得我的文章对您有用,请帮助本站成长」

赞(5) 打赏

觉得文章有用就打赏一下文章作者

支付宝
微信
5

觉得文章有用就打赏一下文章作者

支付宝
微信
标签:

上一篇:

下一篇:

共有 1 条评论 - 9.9 个 CSS 小技巧 让你有更多时间摸鱼

  1. cinarsky Windows NT Chrome 74.0.3729.131

    CSS 文档流技巧,让布局更简单,下次可以试试

博客简介

码云笔记: mybj123.com,一个关注Web前端开发技术的博客,主要记录和总结前端工作中常用的知识及我的生活。
更多博客详情请看关于博客

圈子

关注微信公众号
关注微信公众号

精彩评论

服务热线:
 13888888888

 QQ在线交流