前端基础-CSS(1)

归纳总结CSS中的一些基础内容

说一下css盒模型

  • 可参考百度前端技术学院 第五天学习笔记(CSS盒模型)
  • CSS盒模型本质上是一个盒子,封装周围的HTML元素,它包括:边距,边框,填充,和实际内容
  • 标准盒模型:一个块的总宽度=width+margin(左右)+padding(左右)+border(左右)
  • 怪异盒模型:一个块的总宽度=width+margin(左右)(既width已经包含了padding和border值)
  • CSS3中引入了box-sizing属性box-sizing:content-box;表示标准盒模型box-sizing:border-box表示的是替代盒模型(IE盒模型)

box-sizing的语法和基本用处

  • box-sizing规定两个并排的带边框的框,语法为box-sizing:content-box/border-box/inherit
  • content-box标准盒模型,宽度和高度分别应用到元素的内容框,在宽度和高度之外绘制元素的内边距和边框
  • border-box替代盒模型,为元素设定的宽度和高度决定了元素的边框盒
  • inherit:继承父元素的box-sizing

画一条0.5px的线

  • 参考文章1/参考文章2注意不能直接设置0.5px,每个浏览器显示效果不同
  • 先决条件
    • 屏幕的分辨率要足够高,设备像素比要大于1,即css中的1个像素对应物理屏幕中1个以上的像素点。
    • 对于普通电脑,屏幕物理像素和css像素一一对应,显示的最小单位就是1px。而现在的手机,屏幕物理宽度一般都大于页面显示宽度。例如苹果6s的屏幕分辨率为1334x750像素,但是以375px的宽度显示页面,设备像素比就是750/375=2;此时在css中定义0.5px的宽度,实际上对应物理屏幕的1个像素点,这就是border小于1px的的实现基础。

效果图

  • 【万能方法】meta viewport
    • 这样子就能缩放到原来的0.5倍,如果是1px那么就会变成0.5px。要记得viewport只针对于移动端,只在移动端上才能看到效果。
    • 在移端开发里面一般会把viewport的scale设置成1,其中width=device-width表示将viewport视窗的宽度调整为设备的宽度,这个宽度通常是指物理上宽度。
    • 默认的缩放比例为1,如iphone 6竖屏的宽度为750px,它的dpr=2,用2px表示1px,这样设置之后viewport的宽度就变成375px。这时候0.5px的边就使用我们上面讨论的方法。
    • 这样的话,viewport的宽度就是原本的750px,所以1个px还是1px,正常画就行,但这样也意味着UI需要按2倍图的出,整体面面的单位都会放大一倍
      1
      2
      <meta name="viewport" 
      content="width=device-width, initial-scale=0.5"/>
  • **CSS3中box-shadow**:box-shadow: 0 0.5px 0 #000;设置box-shadow的第二个参数为0.5px,表示阴影垂直方向的偏移为0.5px。这个方法在Chrome和Firefox都非常完美,但是Safari不支持小于1px的boxshadow,所以完全没显示出来了。不过至少找到了一种方法能够让PC的Chrome显示0.5px。
  • CSS3中transform: scale():transform: scale(0.5,0.5);导致Chrome变虚,而粗细几乎没有变化,只有Firefox比较完美看起来是实的而且还很细,效果和直接设置0.5px一样。
  • CSS3中linear-gradientlinear-gradient(0deg, #fff, #000)的意思是:渐变的角度从下往上,从白色#fff渐变到黑色#000,而且是线性的,在高清屏上,1px的逻辑像素代表的物理(设备)像素有2px,由于是线性渐变,所以第1个px只能是#fff,而剩下的那个像素只能是#000,这样就达到了画一半的目的。逻辑分析很完美,实际的效果在各个流览器上面都不完美,效果都是虚的,和完美的0.5px还是有差距。这个效果和scale 0.5的差不多,都是通过虚化线,让人觉得变细了。

【看】CSS画三角形/正方体

  • 三角形/扇形可利用border+transparent实现
  • CSS画正方体
    • 重点:
      • transform-style: preserve-3d;定义所有子元素在3D空间中呈现
      • transform: rotateX(-35deg) rotateY(30deg);整体旋转,这样各个面就不用单独转到歪斜
        • 元素中心为原点,x轴朝右,y轴朝下,z轴屏幕朝外
      • position: absolute;所有面绝对定位,否则各个面竖直分布,无法合成正方形
      • transform: rotateX(90deg) translateZ(50px);注意rotate和translate顺序!旋转后z轴方向改变为向上,故向上平移!
1
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
64
65
66
67
68
69
70
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<title>透视骰子</title>
<style>
.cube {
transform-style: preserve-3d;
/* 重点!没有整体3d旋转则看上去会是一个重叠的平面正方形 */
transform: rotateX(-35deg) rotateY(30deg);
}

.side {
/* 如不绝对定位则各个面竖直分布,无法合成正方形 */
position: absolute;
width: 100px;
height: 100px;
background: rgba(255, 99, 71, 0.6);
border: 1px solid rgba(0, 0, 0, 0.5);
color: white;
text-align: center;
line-height: 100px;
font-size: 50px;
}

/* 1 */
.front {
transform: translateZ(50px);
}

/* 2 */
.bottom {
transform: rotateX(-90deg) translateZ(50px);
}

/* 3 ,注意顺序!旋转后z轴方向为向上,故向上平移 */
.left {
transform: rotateX(90deg) translateZ(50px);
}

/* 4 */
.right {
transform: rotateY(90deg) translateZ(50px);
}

/* 5 */
.top {
transform: rotateY(-90deg) translateZ(50px);
}

/* 6 */
.back {
transform: rotateY(180deg) translateZ(50px);
}
</style>
</head>

<body>
<div class="cube">
<div class="side front">1</div>
<div class="side back">6</div>
<div class="side right">4</div>
<div class="side left">3</div>
<div class="side top">5</div>
<div class="side bottom">2</div>
</div>
</body>

</html>
  • CSS3 transform 属性应用于元素的2D或3D转换。这个属性允许你将元素旋转,缩放,移动,倾斜等
    • rotateX(angle)定义沿着 X 轴的 3D 旋转。
    • translateZ(z)定义 3D 平移,只是用 Z 轴的值。
    • 注意XYZ轴的方向,以及rotate的方向与角度正负的关系
      • 原点位于元素正中心,x轴朝右,y轴朝下,z轴屏幕朝我们
      • rotate方向 左手法则:伸出左手,大拇指指向正轴方向,四个手指的指向即是旋转正向。
    • 重点:rotateX(..) 和translateZ(..)的前后顺序会导致结果不一样!
      • transform: rotateX(90deg) translateZ(50px);意为沿着x轴旋转90度再沿着z轴平移50px,旋转后z轴方向为向上!
      • transform: translateZ(50px) rotateX(90deg);意为沿着z轴平移50px再沿着x轴旋转90度,此时z轴方向为屏幕朝我们!
  • CSS3 transform-style 属性指定嵌套元素是怎样在三维空间中呈现。
    • 注意: 使用此属性必须先使用 transform 属性
    • preserve-3d表示所有子元素在3D空间中呈现
  • rgba:颜色中Alpha为色彩空间,也就是透明度/不透明度
    • 它的范围为0.0(完全透明)到1.0(完全不透明)之间,0.5为半透明
    • rgba(255,255,255,0)则表示完全透明的白色;
    • rgba(0,0,0,1)则表示完全不透明的黑色;

link标签和@import标签的区别

  • link属于html标签,只能放入html源代码中使用,而@importcss提供的,可看作为css样式,作用是引入css样式功能,html和css代码中都能使用。(区别举例参考
  • 页面被加载时,link会同时被加载,而@import引用的css会等到页面加载结束后加载
  • link是html标签,因此没有兼容性,而@import只有IE5以上才能识别。
  • link方式样式的权重高于@import的。
  • link使用方法
    • html文件中:<link href="CSSurl路径" rel="stylesheet" type="text/css" />
  • @import使用方法:
    • css文件中:@import url(CSS文件路径地址);
    • html文件中:
1
2
3
<style type="text/css">
@import url(CSS文件路径地址);
</style>

让footer始终位于页面的最底部

  • 总结:
    • 方法1: 子绝父相,footer用bottom固定在底部
    • 方法2: flexbox,设定父元素高度,子元素中主内容flex:1,等比撑满所有剩余空间,header和footer使用默认的flex:0 1 auto使其只会在空间不足时等比缩小而不会放大,如此footer自然被撑在最下方
      • 父元素高度主内容能撑起剩余空间的前提
      • flexbox默认所有子元素横向排列,需要设置为纵向排列flex-direction:column
1
2
3
4
5
6
7
8
9
10
// 方法1、2的html
<body>
<div class="page">
<header> 头部 </header>
<div class="content">
<p class="内容区"></p>
</div>
<footer> 底部 </footer>
</div>
</body>
  1. 子绝父相:footer使用绝对定位+bottom固定在底部:
1
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
<style type="text/css">
* {
margin: 0;
padding: 0;
}
.page {
box-sizing: border-box;
min-height: 100vh;
position: relative;
padding-top: 20px;
padding-bottom: 20px;
}
.content {
background: red;
}
header {
background: blue;
width: 100%;
height: 20px;
position: absolute;
top: 0;
}
footer {
background: yellow;
width: 100%;
height: 20px;
position: absolute;
bottom: 0;
}
</style>
  1. 使用flexbox方法(阮一峰):父元素设置100vh,子项主内容flex设置为1,header和footer使用默认的flex,则有空余空间时主内容扩张以撑满所有剩余的空间,此时header便会自动吸顶,footer自动吸底
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<style type="text/css">
/* 把body的外边距消除掉效果比较好 */
* {
margin: 0;
padding: 0;
}
.page {
display: flex;
/* 注意:默认是所有子项排列在一行上 */
flex-direction: column;
/* 要flex:1撑起所有剩余高度,则父元素必须固定高度 */
min-height: 100vh;
}
.content {
/* 放大比例设为1,则有剩余空间时撑满剩余空间 */
flex: 1;
background: red;
}
</style>

因为flex子元素的flex默认值是0 1 auto(即0:如果存在剩余空间,也不放大。1:如果空间不足,则该子项格局1的比例缩小。auto:子项初始大小参照我的width和height属性)。而flex:1规定有空余空间时主内容扩张以撑满所有剩余的空间(注意前提是其父容器的尺寸不为零)。除了content,其他flex项都不会占有父元素剩余空间,他们只会按照自己的宽高进行等比缩小,自然就自动吸顶和吸底了。

CSS3新属性:单位vh

vh是相对于视口的高度。视口被均分为100单位的vh

水平、垂直居中的方法

  • 可参考百度前端技术学院 第七天学习笔记(CSS 居中)
  • 例子代码和效果可看codepen
  • 水平居中:
    • text-align: center;文本(父子元素设置都可以),内联/内联块元素/图片(给父元素设置text-align)
    • 定宽块级元素:元素定宽+margin: auto; margin: 0 auto;
      • 注意:子元素 设置margin!
      • 只适用于水平边距(如果margin-topmargin-bottomauto,则其使用值为0),不适用于浮动/内联/绝对/固定定位元素
    • 不定宽块级元素:
      • position: absolute + left: 50% + transform: translateX(-50%)
        • 拓展补充: BFC不能解决绝对定位元素的高度塌陷问题,所以子绝父相时父元素必须给个 高度来避免绝对定位元素脱离文档流的问题
      • display: flex + justify-content: center
  • 垂直居中:必备条件:父元素是盒子容器且高度已经设定)
    • line-height: 行内文本/块内单行文本垂直居中
    • vertical-align: middle,必要时可给块元素设置display: table-cell:特别适用于需要垂直居中不同类型内容的情况
      • 会影响好多啊,图片还要另外设置,可不使用table-cell,而是其父元素用行高替代高度,且字体大小设为0。子元素本身设置vertical-align:middle,避开避开,能不用就不用吧
      • vertical-align 通常不会被继承,基本都在 元素自身上设置。但块元素居中是父元素设置vertical-align,图片居中是图自己设置vertical-align且不需要设置父元素单元格(但是父元素的高度要用行高代替,且字体大小设0),文本是父子都可,难搞
        • 块内多行文本垂直居中!!
        • 行内文本垂直居中
        • 图片垂直居中(还是别了,父元素要用line-height代替height,如果父元素其他内容换行了就很烦,用别的方式实现图片垂直居中吧例子
        • 行内元素或内联块级元素(如图标、按钮、链接等)
      • 注意:vertical-align 某种情况下不作用于span元素 (原因可看《百度前端技术学院 第七天学习笔记(CSS居中)》)
    • 定高块级元素:直接计算子元素的margin-top或margin-bottom,将其设置为(父元素高度-子元素高度)/2
      • 注意:直接设置auto不会起效,如果margin-topmargin-bottomauto,则其使用值为0
        • 但flex可以,父元素设置display:flex,子元素设置margin:auto 0
        • 也可以用 **子绝父相 + top、bottom、left、right设为0 + margin: auto **
    • 不定高块级元素
      • flexbox:父元素使用display: flex;将其设置为弹性盒子父容器,然后设置align-items: center;定义子项在交叉轴上的对齐方式
      • position:absolute + top: 50% + transform: translateY(-50%)
  • 水平+垂直居中:
    • text-align + line-height:块/行内元素单行文本双向居中
    • 父元素display: table-cell + text-align: center + vertical-align: middle:实现行内 元素/图片双向垂直
      • vertical-align限制好多啊,避开它吧,能不用就不用,问了一圈同事没人在用
      • 块元素居中是父元素设置vertical-align,图片居中是图自己设置vertical-align且不需要设置父元素单元格,文本是父子都可,难搞
    • flex:将父元素设置为display: flex,并且设置align-items: center; justify-content: center;
    • 子绝父相 + top、left设为50% + transform: position:absolute +left: 50% + top: 50% + transform: translate(-50%, -50%)
    • 子绝父相 + top、bottom、left、right设为0 + margin: auto:定位为上下左右为0,margin:auto可以实现脱离文档流的居中(子绝父相的情况)
      • 注意: 子元素需要定高定宽!!
      • 原理:当top、bottom为0时,margin-top&bottom设置auto的话会无限延伸沾满空间并平分,当left、right为0时,margin-left&right设置auto会无限延伸占满空间并平分

如何实现图片在某个容器中居中的?

  • 代码和效果见codepen
  • 父元素与图片固定宽高
    • 直接计算并设置子元素margin值
    • 子绝父相 + top、bottom、left、right设为0 + margin:auto
    • 父元素display:flex,子元素margin:auto
  • 图片 不定宽高
    • 父元素设置display: flex、**align-items: center; justify-content: center**
    • 【vertical-align单独用行不通,必须联合字体大小为0,且父元素用行高替代高度】父元素设置 text-align:center,子元素本身设置vertical-align:middle
      • vertical-align:middle可能会造成基线的问题导致垂直不太居中,可参考这篇文章,如果想解决这个偏差就需要设置字体大小为0
      • 放弃这种方法吧,真的麻烦
    • 子绝父相图片设置position: absolute; left: 50%; top: 50%;transform: translate(-50%,-50%);
      1. 不知道自身宽高的情况下,可以利用translate()函数来进行水平垂直居中
      2. 当使用position: absolute;top: 50%;left: 50%;, 是以左上角为原点,故不处于中心位置。
      3. translate(-50%,-50%) 作用是**往上(x轴),左(y轴)移动自身长宽的 50%**,以使其居于中心位置。

如何实现元素的垂直居中

  • 代码和效果见codepen
  • 行内/块内文本:line-height设置为高度
  • 父元素display: flex; align-items: center;
  • 高度确定
    • 元素绝对定位,top:50%,margin-top:-(高度/2)
      • top:50%定位点是左上角,所以需要使用margin-top将其调高自身一半达到垂直居中
    • 父元素设置display:flex,子元素设置margin:auto 0
    • **子绝父相 + top、bottom、left、right设为0 + margin: auto **
  • 高度不确定时,元素**绝对定位+transform:translateY(-50%)**向上移动自身高度的一半
  • 行内/单元格内 图片/文本/块级元素:块元素居中是父元素设置单元格 + vertical-align,图片居中是图自己设置vertical-align且不需要设置父元素单元格(但是父元素的高度要用行高代替,且字体大小设0),文本是父子都可,难搞,能避则避
    • vertical-align 不作用于span元素

width300,height300在屏幕上垂直水平居中

  • 代码和效果见codepen
  • 【子绝父相+top+left+transform】父元素设置position:relative,子元素设置position:absolute; top:50%; left:50%; transform:translate(-50%,-50%)
  • 【子绝父相+top、bottom、left、right设为0+margin: auto】定宽定高元素可用
    • 原理:当top,bottom为0时,margin-top&bottom设置auto的话会无限延伸沾满空间并平分,当left,right为0时,margin-left&right设置auto会无限延伸占满空间并平分
  • 【flex+align-items+justify-content】父元素设置display: flex; align-items: center; justify-content: center;
  • 【flex+margin】父元素设置display:flex,子元素设置margin:auto
  • 【父单元格、vertical-align+子margin: auto】 父元素设置display:table-cell; vertical-align:middle达到垂直居中,子元素设置margin:auto实现水平居中【子元素设置vertical-align不行!!要父元素设置,我真是疯了,vertical-align好复杂555】

关于js动画和css3动画的差异性

  • 渲染线程分为main thread和compositor thread,如果css动画只改变transform和opacity,这时整个CSS动画得以在compositor trhead完成(而js动画则会在main thread执行,然后出发compositor thread进行下一步操作),特别注意的是如果改变transform和opacity是不会layout或者paint的。
  • 区别
    1. 功能涵盖面,js比css大
    2. 实现/重构难度不一,CSS3比js更加简单,性能跳优方向固定
    3. 对帧速表现不好的低版本浏览器,css3可以做到自然降级
    4. css动画有天然事件支持
    5. css3有兼容性问题

display

主要取值有none,block,inline-block,inline,flex,grid等

inline-block、inline和block的区别