CSS 基础
单词换行、断词和空格处理
1、word-break 断词。当行尾放不下一个单词时,决定单词内部该怎么摆放。
- break-all: 强行上,挤不下的话剩下的就换下一行显示呗。霸道型。
- keep-all: 放不下我了,那我就另起一行展示,再放不下,我也不退缩。傲骄型。
2、word-wrap 换行。当行尾放不下时,决定单词内是否允许换行
- normal: 单词太长,换行显示,再超过一行就溢出显示。
- break-word: 当单词太长时,先尝试换行,换行后还是太长,单词内还可以换行。
3、white-space 空格是否合并成一个
- pre: 保留所有的空格和回车,且不允许折行。
- pre-wrap: 保留所有的空格和回车,但是允许折行。
- pre-line: 会合并空格,且允许折行
4、上面这些换行神马的都是针对英文单词,像CJK(中文/日文/韩文)这样的语言就算了,因为他们不需要。
tansition与animation
1、语法
1、transition
transition: property duration timing-function delay;
- property:需要过渡的属性,为提升动画效果,一般使用transform+opacity代替width,left等过度属性;
- duration:过渡动画持续的时间;
- timing-function:动画执行的速率函数;
- delay:动画延迟多久执行。
大部分简单的动画都可由transition来完成,但对于需要重复运动的动画,transition无能为力
2、animation
animation: name duration timing-function delay iteration-count direction fill-mode play-state;
- timing-function:动画的速度曲线,可取ease,ease-in,ease-out,ease-in-out,step-start,step-end,step(int),linear,cubic-bezier(int1,int2,int3,int4);关于step()函数作用可参看这篇文章;
- iteration-count表示动画重复次数,取infinite表示无穷次;
- direction表动画是否反向播放,可取:normal reverse alternate alternate-reverse。当取alternate时,动画函数也反向,如ease-in变为ease-out。
- fill-mode指定在动画执行之前和之后如何给动画的目标应用样式。(在最后一个或者第一个关键帧中定义)
- play-state 定义一个动画是否运行或者暂停。可以通过查询它来确定动画是否正在运行。另外,它的值可以被设置为暂停和恢复的动画的重放。恢复一个已暂停的动画,将从它开始暂停的时候,而不是从动画序列的起点开始在动画。可取running和paused
- mix-blend-mode 描述了元素的内容应该与元素的直系父元素的内容和元素的背景如何混合
2、运用
- transition场景:有一个举报按钮,点击后从页面底部弹出举报弹窗
.report{
//1、确定哪些属性做过渡动画(这里是transform)
will-change:transform;
transition:transform 1s ease-in;
//2、定义该属性的初始状态
transform:translateY(200px);
width:200px;
height:150px;
margin:0 auto;
//3、确定该属性的最终状态
&.reveal{
transform:translateY(0);
}
}
当点击举报按钮时,给其加上.reveal类就可以了。值得一提的是,当去掉reveal类时,会自动有一个和进入动画相反的退出动画,这一点使得用transition做动画非常方便。
- animation场景:做一个加载进度条动画
.loading
span
span
span
.loading{
display: flex;
background-color: #fff;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
align-items:center;
justify-content: center;
z-index:1000;
}
span{
width: 30px;
height: 30px;
margin-left: 10px;
border-radius: 50%;
background-color: #5ECF75;
}
.loading span:nth-child(1) {
animation: loading 1.2s infinite
}
.loading span:nth-child(2) {
animation: loading 1.2s infinite -1s
}
.loading span:nth-child(3) {
animation: loading 1.2s infinite -0.8s
}
@keyframes loading {
0% {
transform: scale(1)
}
20% {
transform: scale(.8)
}
40% {
transform: scale(.6)
}
60% {
transform: scale(.4)
}
80% {
transform: scale(.2)
}
100% {
transform: scale(0)
}
}
可以看到,animation动画代码写起来就很多,比较复杂,适用于需要重复运动的动画。(delay参数可以用负值,如果用正值,那么在动画开始的一瞬间会有延迟,很不和谐,但是又想让每个span的初始状态不一样,这时可以用负延迟,-1s相当于0.2s时的状态,只不过用-1s动画不会有停顿,但用0.2s动画就会停顿0.2s才开始)
3、进阶
动画玩儿的6不6,最重要的在于参数timing-function的使用,transition和animation都有这个参数,它的默认值是ease,可取值有:ease,ease-in,ease-out,ease-in-out,linear,以及cubic-bezier(int1,int2,int3,int4),以下是这些值的运动曲线:
这些其实都是cubic-bezier的特殊情况,分别对应:
通过传不同的值就可以生成不同的运动曲线,这里推荐先在网站http://cubic-bezier.com上生成想要的贝塞尔曲线,再运用到代码中。
避免重排重绘 & 提升合成层
- elem.offsetLeft, elem.offsetTop, elem.offsetWidth, elem.offsetHeight,elem.offsetParent
- elem.clientLeft, elem.clientTop, elem.clientWidth, elem.clientHeight
- elem.getClientRects(), elem.getBoundingClientRect()
- elem.scrollWidth, elem.scrollHeight,elem.scrollLeft, elem.scrollTop
提升合成层:
- will-change 设置为 opacity、transform、top、left、bottom、right(其中 top、left 等需要设置明确的定位属性,如 relative 等)
- hack方法:translateZ(0)
对于较少可能变化的区域,防止页面其他部分重绘时影响这一片,考虑提升至合成层。
before,after 伪元素
<div class="test"></div>
.test{
width:100px;
height: 100px;
padding:30px;
background: red;
position: relative;
&:before,&:after{
content:'';
position: absolute;
left:0;
transform: translateX(calc(50px - 50%));
}
&:before{
content:'before';
}
&:after{
content:'after';
height:30px;
line-height: 30px;
background-color: green;
top:-40px;
}
}
image.png
注意点:
1、before,after 默认宽高由content 内容撑开,也可手动设置;
2、默认位置是左上角,从 content 处开始,而不是 padding
3、当对before,after显示设置top:0,left:0时,可回归到左上角,从padding 处开始
4、transform: translateX(calc(50px - 50%)); 是实现与内容水平居中对齐的关键
获取或修改before/after伪元素的样式:看这里
伪元素与伪类的区别:伪元素实现的效果无法单独用伪类实现,必须修改dom结构才可以实现相同的效果。常用的伪元素:before,after,first-line,first-letter
渐变的遮罩层
如果你做的遮罩是通过hide()或show()来控制的,那么意味着你做的遮罩的opacity是突变的,而不是线性减少或增加,给用户的感觉就好像闪了一下,体验不佳。本文就是解决这个问题。
看下这个html结构
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
<title>搜狐墨客</title>
<style>
.mask{
position: fixed;
top:0;
left: 0;
width: 100%;
height: 100%;
background-color: #ccc;
transition:opacity 0.3s;
opacity: 0;
z-index: -1;
}
.opacity{
opacity: 0.3;
}
.content{
position: absolute;
z-index: 2;
width: 80%;
height: 300px;
background-color: green;
bottom:-300px;
transition:bottom 0.3s;
left: 0;
right: 0;
margin: 0 auto;
}
.top{
bottom:10px;
}
button{
width: 100px;
height: 100px;
}
header{
height: 100px;
background-color: red;
position: fixed;
top:0;
width: 100%;
}
main{
margin-top: 100px;
height: 500px;
background-color: #fff;
}
footer{
height: 67px;
background-color: green;
}
</style>
</head>
<body>
<div id="content">
<header>header</header>
<main>main
<button class="label1">上去</button>
<button class="label2">下来</button>
</main>
<footer>footer</footer>
</div>
<div class="mask">
</div>
<div class="content">
确定删除吗?
</div>
<script src="../static/js/thirdLib/zepto.min.js"></script>
<script>
var $content=$('.content'),
$mask=$('.mask'),
$button1=$('.label1'),
$button2=$('.label2');
$button1.on('click', function(event) {
console.log('q');
debugger;
$mask.addClass('opacity').css('z-index', 1);;
$content.addClass('top');
/* Act on the event */
});
$mask.on('click', function(event) {
$content.removeClass('top');
$mask.removeClass('opacity');
setTimeout(function(){
$mask.css('z-index', -1);
},300)
});
</script>
</body>
</html>
实现原理就是动态改变mask的z-index值,动画开始时,提升mask的z-index使其遮住#content的内容并让其opacity顺利线性增加,结束动画时,要注意先让其opacity线性减少至0后再改变其z-index值使#content内容展现出来,这里使用了setTimeout来等待opacity完成动画。
z-index 的正确使用
看这里 z-index
CSS 选择器为何是从右向左查询
总结一点就是:从右向左的匹配在第一步就筛选掉了大量的不符合条件的最右节点(叶子节点);而从左向右的匹配规则的性能都浪费在了失败的查找上面。虽然从右向左查找也会有失败的查找,但平均来说它还是更高效,因为大多时候,一个DOM树中,符合匹配条件的节点(如.mod-nav h3 span)远远远远少于不符合条件的节点。