# 提高幸福感的css技巧
| 进入:55 个提高你 CSS 开发效率的必备片段 |
|---|
# 建议使用 padding 代替 margin
padding 和 margin 两个是常用的属性,但我们知道属于同一个 BFC 的两个相邻 Box 的 margin 会发生重叠,所以如果 margin 使用的过于频繁的时候,Box 的垂直距离可能就会发生重叠。
所以我们在使用 margin 的时候一定要注意collapsing margins问题。
# position:fixed 降级问题
曾经的你是不是遇到吸顶效果,就是使用 position:fixed 这个属性。其实如果其
父元素中有使用 transform,fixed 的效果会降级为 absolute
如果这个直接父级内的元素存在滚动的情况,那就加上 overflow-y: auto。
# 合理使用变量
一般设计稿中的某一类的文字(元素)都是用相同的字体大小、颜色、行高等样式属性,所以这些值我们不必每次都重复写,因为当 UI 更新设计方案,你需要改的地方就很多了。这些重复使用的值我们完全可以存放在变量里面
Sass 和 Less 稍微有点区别:
// sass
$direction: left;
// less
@direction: left;
2
3
4
当然 CSS 原生也是存在变量的,使用规则如下:
变量定义的语法是: --*; // 为变量名称。
变量使用的语法是:var();
- 无论是变量的定义和使用只能在
声明块 {} 里面 - CSS 变量字符限制为:
[0-9]、[a-zA-Z]、_、-、中文和韩文等。
: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);
}
2
3
4
5
6
7
8
9
10
11
# 使用Mixin归类重复样式
和重复变量一样,重复的样式也可以归类。我觉得优秀的代码其中有一条肯定是代码的复用性强
最后的效果可能就是在一个元素里面放了很多 class,这个时候,mixin( 可以理解成 class 中的 class )就能发挥它的作用了
.font-description {
.font-des-style(24px,#fff,1.5em);
.line-camp(2);
}
/* // less */
/* 多行显示 */
.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;
}
.font-des-style( @fontSize, @color, @lineHeight, @textAlign:left ) {
font-size: @fontSize;
color: @color;
line-height: @lineHeight;
text-align: @textAlign;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 1px方案
# 使用伪类 + transform
.border_bottom {
overflow: hidden;
position: relative;
border: none!important;
}
.border_bottom:after {
content: "";
display: block;
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);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 使用 box-shadow 模拟
.border_bottom {
box-shadow: inset 0px -1px 1px -1px #d4d6d7;
}
2
3
# 一种更加精细又绵长的方案
.min-device-pixel-ratio(@scale2, @scale3) {
@media screen and (min-device-pixel-ratio: 2), (-webkit-min-device-pixel-ratio: 2) {
transform: @scale2;
}
@media screen and (min-device-pixel-ratio: 3), (-webkit-min-device-pixel-ratio: 3) {
transform: @scale3;
}
}
.border-1px(@color: #DDD, @radius: 2PX, @style: solid) {
&::before {
content: "";
pointer-events: none;
display: block;
position: absolute;
left: 0;
top: 0;
transform-origin: 0 0;
border: 1PX @style @color;
border-radius: @radius;
box-sizing: border-box;
width: 100%;
height: 100%;
@media screen and (min-device-pixel-ratio: 2), (-webkit-min-device-pixel-ratio: 2) {
width: 200%;
height: 200%;
border-radius: @radius * 2;
transform: scale(.5);
}
@media screen and (min-device-pixel-ratio: 3), (-webkit-min-device-pixel-ratio: 3) {
width: 300%;
height: 300%;
border-radius: @radius * 3;
transform: scale(.33);
}
}
}
.border-top-1px(@color: #DDD, @style: solid) {
&::before {
content: "";
position: absolute;
left: 0;
top: 0;
width: 100%;
border-top: 1Px @style @color;
transform-origin: 0 0;
.min-device-pixel-ratio(scaleY(.5), scaleY(.33));
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# 从html元素继承box-sizing
在大多数情况下我们在
设置元素的 border 和 padding 并不希望改变元素的 width,height 值,这个时候我们就可以为该元素设置box-sizing:border-box;
html {
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
2
3
4
5
6
这样的好处在于他不会覆盖其他组件的 box-sizing 值,又无需为每一个元素重复设置 box-sizing: border-box;。
# 内联首屏关键CSS
性能优化中有一个重要的指标 —— 首次有效绘制(FMP),即指
页面的首要内容(primary content)出现在屏幕上的时间。这一指标影响用户看到页面前所需等待的时间,而 内联首屏关键 CSS(即 Critical CSS,可以称之为首屏关键 CSS) 能给用户一个更好的心理预期
既然是内联关键 CSS,也就说明我们只会将少部分的 CSS 代码直接写入 HTML 中。至于内联哪些 CSS 你可以使用 Critical。
# 文字超出省略
.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;
}
2
3
4
5
6
7
8
-webkit-box-orient: vertical在使用 webpack 打包的时候这段代码会被删除掉,原因是 optimize-css-assets-webpack-plugin 这个插件的问题。
可以使用如下的写法:
.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 */
}
2
3
4
5
6
7
8
9
10
# 文本省略号显示
前提是其容器宽度固定
div {
white-space:nowrap;/* 规定文本是否折行 */
overflow: hidden;/* 规定超出内容宽度的元素隐藏 */
text-overflow: ellipsis;
/* 规定超出的内容文本省略号显示,通常跟上面的属性连用,因为没有上面的属性不会触发超出规定的内容 */
}
2
3
4
5
6
折行(能主动控制行数,这里设置的超出 4 行显示省略号):
div {
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box; /* 将对象作为弹性伸缩盒子模型显示 */
-webkit-line-clamp: 4; /* 控制最多显示几行 */
-webkit-box-orient: vertical; /* 设置或检索伸缩盒对象的子元素的排列方式 */
}
2
3
4
5
6
7
# 文字两端对齐
<div>姓名</div>
<div>手机号码</div>
<div>账号</div>
<div>密码</div>
2
3
4
div {
margin: 10px 0;
width: 100px;
border: 1px solid red;
text-align: justify;
text-align-last:justify
}
div:after{
content: '';
display: inline-block;
width: 100%;
}
2
3
4
5
6
7
8
9
10
11
12
# 快速重置表单元素 unset
button {
background: none;
border: none;
color: inherit;
font: inherit;
outline: none;
padding: 0;
}
2
3
4
5
6
7
8
/* 其实你只需要这样就可以(像平时用的特别多的 input textarea ): */
button { all: unset; }
2
# 改变盒模型的宽高计算方式
box-sizing:border-box;
# 改变滚动条样式
滚动条的组成分为三个部分,滚动条容器 scrollbar, 滚筒条轨道 scrollbar-track,滚动条滑块 scrollbar-thumb。
div::-webkit-scrollbar {
/* 这里的宽是指竖向滚动条的宽,高是指横向滚动条的高*/
width: 16px;
height: 16px;
background: pink;
}
div::-webkit-scrollbar-thumb {
border-radius: 10px;
background:
linear-gradient(red,orange);
}
2
3
4
5
6
7
8
9
10
11
# 最后一个 div 不显示下边框
div:not(:last-child) /* 匹配非最后一个 div 元素的 div 元素 */
# 设置文本俩端对齐
div { width: 100px; padding: 0 10px; background: pink; margin-bottom: 10px; text-align-last:justify; /* 这是关键属性 */}
<div>账号</div><div>密码设置</div><div>手机号</div>
2
3
# 规定图像展示方式
TIP
object-fit:fill | contain | cover | none | scale-down
# sticky导航
header {
position: sticky;
top: 0;
}
2
3
4
<main>
<header>
<h1>This is my sticky header!</h1>
</header>
<section>This is my content</section>
</main>
2
3
4
5
6
作用范围
header 只会附着在父元素(这里是<main>标签)所在区域。“sticky 父元素”决定了“sticky 子元素”的作用范围
# 高手都在用!9个实用小技巧提升你的动效设计功力
- 挤压和拉伸
在动画中,挤压和拉伸代表了物体的重力,质量,重量和灵活性。举例来说,当一个弹球在它撞击地面时会发生形态变化,就是挤压和拉伸。- 按钮在交互时的挤压和拉伸
- 挤压和拉伸被应用于侧边栏
- 预期动作
让观众能预先知道接下来将会发生什么,它是先于下一步会发生的动作。举例来说,迪士尼动画里经常有从高空往下跳跃时会先弯曲膝盖再跳,正在跑步的人要停止跑步前会逐渐变慢步伐等等。- 悬停的交互通常会暗示这个按钮是可以点的
- 在有水平滚动界面里,通常在交互时会显示下一个元素的部分内容。这其实是一个很好的例子,因为它是在告知用户下一步的一些信息。
- 时间节奏
速度太慢,用户会不耐烦;速度太快,用户又会错过一些内容。
大多数 UI动画在200-600ms之间,其中悬停和反馈交互时长大约为300ms,精细的转场动画大约在500ms。 - 渐快与渐慢
在现实世界中,大多数物体都遵循着缓动运动规律。也就是说,物体的运动并不会瞬间开始或瞬间结束,就像一个物体自由落体,也是一开始很慢后面才会变快。 - 呈现方式
- 弧形轨迹
一个从高处抛出的小球,运动轨迹会做抛物线轨迹运动,弧线能使物体的运动更加自然。 - 附属动作
在动画中,次要动作能够起到烘托主要动作,比如动画中的角色在走路时,头部的晃动就是次要动作,却能够让角色行走显得更加自然。- 按钮边上的粒子效果强化了主按钮的点击效果
- 夸张和吸引力
- FAB夸张的交互形式
- 对于支付这么重要功能的按钮,通过夸张的动效引起用户的注意
- 跟随动作和重叠动作
想象一只兔子从高处跳下来,当兔子开始起跳时,它的耳朵动作会与身体动作发生错位。然后当它着陆时,它的身体停下来了,但是耳朵还在动。前者称之为跟随动作,后者被称为重叠动作。其原理说的就是:没有任何一种物体会突然停止,物体的运动是一个部分接着另一个部分的。- 界面有一定的回弹,会显得更加自然。
- 当界面滚动时,文字会跟随图片的运动,图片与文字以不同的速度运动会更加自然。
# 响应式布局方法总结
响应式布局指的是同一页面在不同屏幕尺寸下有不同的布局。传统的开发方式是PC端开发一套,手机端再开发一套,而使用响应式布局只要开发一套就够。
# 响应式布局方法一:媒体查询
使用@media媒体查询可以针对不同的媒体类型定义不同的样式,特别是响应式页面,可以针对不同屏幕的大小,编写多套样式,从而达到自适应的效果。举例来说:
@media screen and (max-width: 960px){
body{
background-color:#FF6699
}
}
@media screen and (max-width: 768px){
body{
background-color:#00FF66;
}
}
@media screen and (max-width: 550px){
body{
background-color:#6633FF;
}
}
@media screen and (max-width: 320px){
body{
background-color:#FFFF00;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
通过max-width设置样式生效时的最大分辨率,上述的代码分别对分辨率在0~320px,320px~550px,550px~768px以及768px~960px的屏幕设置了不同的背景颜色。
媒体查询的缺点也很明显,如果在浏览器大小改变时,需要改变的样式太多,那么多套样式代码会很繁琐。
# 响应式布局方法二:百分比%
- 子元素的
top和bottom如果设置百分比,则相对于直接非static定位(默认定位)的父元素的高度,同样,子元素的left和right如果设置百分比,则相对于直接非static定位(默认定位的)父元素的宽度。 - 子元素的
padding如果设置百分比,不论是垂直方向或者是水平方向,都相对于直接父亲元素的width,而与父元素的height无关。 - 子元素的
margin如果设置成百分比,不论是垂直方向还是水平方向,都相对于直接父元素的width border-radius不一样,如果设置border-radius为百分比,则是相对于自身的宽度
# 响应式布局方法三:vw/vh
css3中引入了一个新的单位vw/vh,与视图窗口有关,vw表示相对于视图窗口的宽度,vh表示相对于视图窗口高度。 任意层级元素,在使用vw单位的情况下,1vw都等于视图宽度的百分之一。
与百分比布局很相似,但更好用。
# 响应式布局方法四:rem
rem单位是相对于字体大小的html元素,也称为根元素。 默认情况下,html元素的font-size为16px。所以此时1rem = 16px。
# 固定底部内容
TIP
- 随着CSS3的来临,最完美的实现方式是使用
Flexbox。实现的关键就是使用不太被关注的flex-grow属性,可以在我们的内容标签元素(比如div)中使用。 - flew-grow是用来控制一个flex元素相对它同等级flex元素的自身可扩充的空间。如果我们使用flex-grow: 0,那这个flex元素就完全不会扩展了。所以我们需要把
头部和底部之间的内容标签元素设置为flex-grow: 1或者flex-grow: auto,这样内容部分就会自动填充满头部和底部之外的所有空间。 - 为了避免底部内容受内容部分扩充空间的影响,我们给
footer底部元素flex-shrink: 0属性。flex-shrink的作用与flex-grow是恰恰相反,用来控制flex元素收缩的空间,这里我们给了flex-shrink: 0就是为了底部footer的大小不受影响。
# CSS最小和最大(宽度/高度)知识点及优缺点
min-width
默认值是auto,它解析为0。
# 混合模式
在CSS中,有两个属性负责混合。mix-blend-mode用于混合DOM元素,background-blend-mode用于组合多个CSS背景。
# mix-Blend-Mode
<div class="circle"></div>
<p class="blend-me">Blend Me</p>
2
.circle {
margin: 1rem auto;
width: 107px;
height: 107px;
border-radius: 50%;
background: #8857bf;
}
.blend-me {
text-align: center;
font-size: 32px;
font-weight: bold;
mix-blend-mode: overlay;
margin-top: -39px;
color: rgba(125, 7, 7, 0.3);
}
body {
background: #e4d4f5;
font-family: Roboto, sans-serif;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 带文字的图片
.hero-title {
color: #000;
mix-blend-mode: overlay;
}
2
3
4
播放按钮
<article>
<div class="article__thumb">
<svg width="64" height="64" xmlns="http://www.w3.org/2000/svg">
<g fill="none" fill-rule="evenodd">
<circle class="play__base" fill="#FFF" cx="32" cy="32" r="32"/>
<path class="play__icon" d="M43.377 33.98L27.54 46.655c-1.075.856-2.626.004-2.536-1.335l.185-25.762c.005-1.34 1.566-2.032 2.564-1.195L43.441 31.52c.776.65.735 1.855-.064 2.459z" fill="#000" fill-rule="nonzero"/>
</g>
</svg>
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/182774/thumb.png" alt="">
</div>
<div class="article__meta">
<h2>The Benefits of Going Outside</h2>
<p>By Ahmad Shadeed</p>
</div>
</article>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
body {
font-family: Roboto, sans-serif;
max-width: 700px;
margin: 0 auto;
padding: 1rem;
line-height: 1.45;
}
article {
position: relative;
width: 300px;
background: #f5f5f5;
box-shadow: 0 3px 5px 0 rgba(0,0,0,0.08);
border-radius: 7px;
overflow: hidden;
transition: 0.3s ease-out;
&:hover {
box-shadow: 0 21px 61px 0 rgba(0, 0, 0, 0.40);
svg {
mix-blend-mode: normal;
}
.play__base {
fill: #005FFF;
}
.play__icon {
fill: #fff;
}
}
svg {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
mix-blend-mode: screen;
}
h2 {
font-size: 20px;
font-weight: bold;
margin-bottom: 0.25rem;
}
p {
font-size: 14px;
}
}
.article__meta {
padding: 0.5rem;
}
.article__thumb {
position: relative;
height: 210px;
img {
width: 100%;
height: 100%;
object-fit: cover;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63