CSS
CSS
-
CSS盒模型
页面上任何一个元素我们都可以看成是一个盒子,盒子会占用一定的空间和位置,他们之间相互制约,就形成了网页的布局
w3c的盒模型的构成: content, border, padding, margin
标准盒模型 width = content IE盒模型(怪异盒模型) width = content + padding + border
box-sizing: content-box || border-box || inherit; /* 当设置为box-sizing: content-box时, 将采用标准模式解析计算,也是默认模式; 当设置为box-sizing: border-box时,将采用IE盒模式解析计算 */
-
CSS选择器以及优先级
基础选择器
1). 通用选择器; 2). 标签选择器; 3). class选择器; 4). id选择器
组合选择器
1). 多元素选择器 E,F; 2). 后代元素选择器 E F; 3). 子元素选择器 E>F; 4). 毗邻选择器 E+F
属性选择器
1). 匹配所有具有att属性的E元素E[att]; 2). 匹配所有att属性等于val的E元素E[att=val]; 3). 匹配所有att属性具有多个空格分隔的值,其中一个值等于val的E元素E[att~=val]; 4). 匹配所有att属性具有多个连字号分隔(hyphen-separated)的值,其中一个值以val开头的E元素E[att |= val]
伪类选择器
伪元素
CSS选择器的优先级
内联 > ID选择器 > 类选择器 > 标签选择器
选择器优先级的规定,最常用的方法是给不同的选择器分配权值:
id选择器优先级很高,权值为100 class、属性和伪类选择器的权值为10 标签选择器权值为1 在比较样式的优先级时,只需统计选择符中的id、class和标签名的个数,然后把相应的权值相加即可,最后根据结果排出优先级 权值较大的优先级越高 权值相同的,后定义的优先级较高 样式值含有!important,优先级最高
div .class1 #people的权值等于1+10+100=111 .class2 li #age的权值等于10+1+100=111 如果第二个选择器后定义样式,则第二个的优先级要高
浏览器CSS匹配不是从左到右进行查找,而是从右到左进行查找,这是为了尽早过滤掉一些无关的样式规则和元素
-
px, em, rem
px: 相对长度单位,像素px是相对于显示器屏幕分辨率而言的;
em: 相对长度单位,相对于当前对象内文本的字体尺寸;
rem: 相对长度单位,相对于HTML根元素字体尺寸大小, 通过修改根元素字体大小修改所有字体大小;
-
CSS实现0.5px
(1). 缩放 先画一条1px的线,再通过transfrom scaleY(0.5)
(2). 更改meta标签的viewport
-
CSS样式的引入
link是html方式, @import是css方式
link最大限度支持并行下载,@import过多嵌套导致串行下载,出现FOUC(白屏)
-
block, inline, inline-block
block元素: div, form, table, p, pre, h1~h6, dl, ol, ul;
inline元素: span, a, strong, em, lable, input, select, textarea, img, br
display: block
(1).block元素会独占一行,多个block元素会各自新起一行; (2). block元素可以设置width, height; (3). block元素可以设置margin和padding
display: inline
(1). inline元素不会独占一行,多个相邻的行内元素会排列在同一行,直到一行排列不下,才会新换一行,其宽度随元素的内容而变化; (2). inline元素设置width, height属性无效; (3). inline元素只能产生水平方向的边距效果(margin, padding),竖直方向无效
display: inline-block
简单的来说就是将对象呈现inline对象,但是对象的内容作为block对象呈现。之后内联对象会被排列在同一行内。比如我们可以给一个linka元素inline-block属性值,使其既具有block宽度高度特性又具有inline的同行特性
-
display: none与visibility: hidden的区别
联系: 他们都能让元素不可见
区别: (1). display: none会让元素完全从dom树中消失,渲染的时候不占据任何空间;visibility: hidden; 不会让元素从渲染树消失,元素仍然会占据空间,只是内容不可见
(2). display: none是非继承属性,子孙节点消失是由于元素从dom树消失造成的,通过修改子孙节点属性无法显示, visibility: hidden是继承属性,子孙节点消失由于继承了hidden通过设置visibility: visible可以让子孙节点显示;
(3). 修改常规元素的display通常会造成文档重排。修改visibility属性只会造成本元素的重绘
opacity:0则仅仅不可见,但仍可被浏览器发现,也就能触发各种事件。通过浏览器调试工具即可得出此结论。
-
<a href=""></a>全部作用
(1). 外部页面链接; (2). 本地页面链接; (3). 锚点链接: 在浏览一些网页的时候大都在网页的上方有一个固定住的导航条,上边会列出下方显示内容的版块分区。当点击导航条中的一个版块的时候他会自动的跳转到指定的版块,这是页面内部的区域跳转。; (4). 其他功能性的链接;
-
伪类和伪元素的区别
1). 伪类(pseudo-classes) 其核心就是用来选择DOM树之外的信息,不能够被普通选择器选择的文档之外的元素,用来添加一些选择器的特殊效果。比如:hover, :active等,由于状态的变化是非静态的,所以元素达到一个特定状态时,它可能得到一个伪类的样式;当状态改变时,它又会失去这个样式,由此可以看出,它的功能和class有些类似,但它是基于文档之外的抽象,所以叫伪类 2). 伪元素(pseudo-elements) DOM树没有定义的虚拟元素,核心就是需要创建通常不存在于文档中的元素,比如::before, ::after它选择的元素指定内容,表示选择元素内容的之前内容或之后内容。伪元素控制的内容和元素是没有差别的,但是它本身只是基于元素的抽象,并不存在于文档中,所以称为伪元素,用于将特殊的效果添加到某些选择器
伪类与伪元素的区别
表示方法: 伪类在语法上用:表示,伪元素在语法上用::表示 定义不同: 伪类即假的类,可以添加类来达到效果,伪元素即假元素,需要通过添加元素才能达到效果
总结: 伪类和伪元素都是用来表示文档树以外的'元素'; 伪类和伪元素分别用单冒号:和双冒号::来表示; 伪类和伪元素的区别,关键点在于如果没有伪元素(或伪类)是否需要添加元素才能达到效果,如果是则是伪元素,反之则是伪类
相同之处
伪类和伪元素都不出现在源文件和DOM树中。也就是说在html源文件中是看不到伪类和伪元素的。
不同之处
伪类其实就是基于普通DOM元素而产生的不用状态,他是DOM元素的某一特征。伪元素能够创建在DOM树不存在的抽象对象,而且这些抽象对象是能够访问到的
-
flex布局
容器属性:
flex-direction: 主轴方向, flex-wrap: 是否换行, flex-flow: flex-direction与flex-wrap的简写, justify-content: 主轴的对齐方式, algin-items: 交叉轴的对齐方式, align-content: 多根轴线的对齐方式
项目属性:
order: 属性定义项目的排列顺序。数值越小,排列越靠前,默认为0。 flex-grow: 项目的放大比例 flex-shrink: 项目的缩小比例 flex-basis: 属性定义了在分配多余空间之前,项目占据的主轴空间(main size) flex: flex-grow, flex-shrink, flex-basis的简写 align-self: 属性允许单个项目有与其他项目不一样的对齐方式(auto表示继承父类无父类等同于stretch) 首先`flex`属性是`flex-grow`, `flex-shrink`, `flex-basis`的简写形式; `flex-grow`: 定义项目的放大比例,即如果子元素未充满父元素,会按照一定的比例放大各个子元素,默认值为0, 按比例放大 `flex-shirnk`: 定义项目的缩小比例,即如果子元素的宽度超过父元素的宽度,会按照一定的比例缩小子元素,默认值为0, 根据缩减系数和元素大小来计算 `flex-basis`: 给上面两个属性分配多余空间之前,计算项目是否有多余空间,默认值为auto,即项目本身的大小 所以`flex: 1`的完整写法是 ``` flex-grow: 1; flex-shrink: 1; flex-basis: 0% ```
-
position
static: 默认值, 没有定位,元素出现在正常的流中;
relative: 相对于默认位置(即static时的位置)进行偏移,即定位基点是元素的默认位置;
fixed: 相对于视口进行偏移,即定位基点是浏览器窗口;
absolute: 相对于上级元素(一般是父元素(值不为static))进行偏移,即定位基点是父元素;
sticky: 它会产生动态效果,很像relative和fixed的结合 当页面滚动,父元素开始脱离视口时,只要与sticky元素的距离达到生效门槛,relative定位自动切换为fixed定位,等到父元素完全脱离视口时(即完全不可见),fixed定位自动切换回relative定位;
inherit: 从父元素继承position属性的值
-
浮动与清除浮动
脱离文档流,也就是将元素从普通的布局排版中拿走,其他盒子在定位的时候,会当作脱离文档流的元素不存在而进行定位
当容器的高度为auto,且容器的内容中有浮动的元素,在这种情况下,容器的高度不能自动伸长以适应内容的高度,使得内容溢出到容器外面而影响(甚至破坏)布局的现象叫浮动溢出,为了防止这个现象的出现,叫CSS清除浮动
.news { background-color: gray; border: solid 1px black; /* method 2: 给浮动元素的容器添加overflow: hidden 或者overflow: auto */ overflow: hidden; } .img { background-color: #bfa; width: 200px; height: 200px; float: left; } p { float: right; } /*method 1: 使用带clear属性的空元素 */ .clear { clear: both; } <div class="news"> <div class="img"></div> <p>Some text</p> <div class="clear"></div> </div>
(1). 方法一: 使用带clear属性的空元素
优点: 简单,代码少,浏览器兼容性好
缺点: 需要添加大量无语义的html元素,代码不够优雅,后期不容易维护
(2). 方法二: 使用CSS的overflow属性
(3). 方法三: 给浮动的元素的容器也添加浮动
(4). 使用邻接元素处理 (给浮动元素后面的元素添加clear属性)
(5). 使用CSS的:after伪元素
给浮动元素的容器添加一个clearfix的class,然后给这个class添加一个:after伪元素
-
BFC以及高度塌陷
BFC是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面元素,反之亦然。我们可以利用BFC的这个特性来做很多事。
阻止元素被浮动元素覆盖 可以包含浮动元素 阻止相邻元素的margin合并
BFC(Block Formatting Context) 块级格式化上下文 + BFC是一个CSS中的一个隐含的属性,可以为一个元素开启BFC 开启BFC该元素会变成一个独立的布局区域 + 元素开启BFC后的特点: 1. 开启BFC的元素不会被浮动元素所覆盖 2. 开始BFC的元素子元素和父元素外边距不会重叠 3. 开启BFC的元素可以包含浮动的子元素
+ 可以通过一些特殊方式来开启元素的BFC: 1. 设置元素的浮动(不推荐) 2. 将元素设置为行内块元素(不推荐) 3. 将元素的overflow设置为非visible的值 + 常用的方式 为元素设置 overflow:hidden 开启其BFC 以使其可以包含浮动元素 使元素开启BFC功能,开启BFC的方法有(1). 浮动(float值不为none); (2). 行内块元素(display: inline-block); (3)设置overflow(overflow不为visible); (4). 开启定位position(absolute, fixed) 可以使用伪元素`::after`解决这个问题(开启浮动导致的高度塌陷问题)
-
实现单行文本溢出显示
.text { width: 100px; margin: 0 auto; } .inner { overflow: hidden; /*文本不会换行*/ white-space: nowrap; /*当文本溢出包含元素时,以省略号表示超出的文本*/ text-overflow: ellipsis; } <div class="text"> <div class="inner">前几天的美团笔试五道题就a了半道,今天下午两点通知我七点面试,总共40分钟,面试管知识面也太广了吧 </div> </div>
-
ul内部除最后一个li以外设置右边框效果
1). last-child
ul li { border-right: 1px solid blue; } ul li:last-child { border-right: unset }
2). nth-last-of-type/nth-last-child
ul li { border-right: 1px solid blue; } ul li:nth-last-of-type(1) { border-right: unset } /* or */ ul li:nth-last-of-child(1) { border-right:unset }
3). not
ul li:not(:last-child) { border-right: 1px solid blue; }
-
CSS如何实现一个半圆
/*上半圆*/ .semi-circle { width: 100px; height: 50px; color: #bfa; border-radius: 50px 50px 0 0; } /*下半圆*/ .semi-circle2 { width: 100px; height: 50px; color: #bfa; border-radius: 0 0 50px 50px; } /*左半圆*/ .semi-circle3 { width: 50px; height: 100px; color: #bfa; border-radius: 50px 0 0 50px; } /*右半圆*/ .semi-circle4 { width: 50px; height: 100px; color: #bfa; border-radius: 0 50px 50px 0 }
-
CSS实现三角形
.triangle { width: 0; height: 0; border-style: solid; border-width: 250px 250px 250px 250px; border-color: red transparent transparent transparent; }
-
水平垂直居中
<div class="outer"> <div class="inner">Hello, world</div> </div> .outer { width: 300px; height: 300px; border: 1px solid #999; } .inner { width: 100px; height: 100px; border: 1px solid #999; }
flex方案
.outer { display: flex; justify-content: center; /* 水平居中 */ align-items: center; /* 垂直居中 */ } /*method 2*/ .outer { display: flex; } .inner { margin: auto; }
grid方案
.outer { display: grid; } .inner { justify-self: center; align-self: center; } /*method 2*/ .outer { display: grid; } .inner { margin: auto; }
absolute + transform
.outer { position: relative; } .inner { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); }
-
水平居中
margin: auto
.inner { display: block; margin: 0 auto; }
text-aligin + inline-block
.outer { text-align: center } .inner { display: inline-block; text-align: left } /*上面代码中的 text-align: center; 会使文本居中,但是对块级元素无效,如果将元素设置为 inline-block,该元素就会被当做文本对待,从而实现元素居中。*/
.outer { position: relative; } .inner { position: absolute; left: 0; right: 0; margin: auto; }
.outer { position: relative; } .inner { position: absolute; left: 50%; transform: translate(-50%, 0); }
-
垂直居中
垂直居中
table-cell + vertical-align .outer { display: table-cell; vertical-align: middle; } inline-block + line-height .outer { line-height: 300px; } .inner { line-height: initial; /* 重置 */ vertical-align: middle; display: inline-block; }
.outer { position: relative; } .inner { position: absolute; top: 0; bottom: 0; margin: auto; }
.outer { position: relative; } .inner { position: absolute; top: 50%; transform: translate(0, -50%); } <!-- transform中translate偏移的百分比就是相对于元素自身的尺寸而言的。 -->
-
两栏布局的方法
(1). 方法一: 浮动布局
div { height: 500px; } #aside { width: 300px; background-color: yellow; float: left; } #main { background-color: aqua; margin-left: 300px; } <div id="aside"></div> <div id="main"></div>
总结: 左侧栏固定宽度向左浮动,右侧主要内容用margin-left留出左侧栏的宽度,默认宽度为auto,自动填满剩下的宽度
(2). 浮动布局+负外边距(双飞翼布局的两栏版)
div{ height:500px; } #aside{ width:300px; background-color:yellow; float:left; margin-right:-100%; } #main{ width:100%; float:left; } #content{ margin-left:300px; background-color:aqua; } <div id = "aside"></div> <div id = "main"> <div id = "content"></div> </div>
总结: 左侧固定栏指定一个右侧的100%的负外边距,为整个屏幕的宽度,这就使得main的最左侧与屏幕的最左侧对齐; 此时main的宽度是100%所以需要为其子内容指定左外边距
(3). 绝对定位
#aside { position: absolute; left: 0; width: 200px; background-color: #bfa; } #main { margin-left: 200px; background-color: yellow; } <div id="aside"></div> <div id="main"> <div id="content"></div> </div>
(4). flex
#container{ display:flex; } #aside{ flex:0 0 200px; } #main{ flex: 1 1; } <div id="container"> <div id = "aside"></div> <div id = "main"></div> </div>
-
三栏布局
(1). 绝对定位
html,body{ margin:0; padding:0; height:100%; } div{ height:100%; } #left{ width:200px; background-color:yellow; position:absolute; top:0; left:0; } #main{ background-color:aqua; margin-left:200px; margin-right:300px; } #right{ width:300px; background-color:orange; position:absolute; top:0; right:0; } <div id = "left"></div> <div id = "main"></div> <div id = "right"></div>
总结: 左侧栏和右侧栏分别用绝对定位固定在左侧和右侧,中间栏利用margin-left和margin-right空出左右栏的位置
(2). 浮动+负外边距
html,body{ margin:0; padding:0; height:100%; } div{ height:100%; } #left{ width:200px; background-color:yellow; float:left; margin-left:-100%; } #main{ background-color:aqua; width:100%; float:left; } #right{ width:300px; background-color:orange; float:left; margin-left:-300px; } #content{ margin-left:200px; margin-right:300px; } <div id = "main"> <div id="content"></div> </div> <div id = "left"> </div> <div id = "right"> </div>
总结: 1). 中间栏的div写在最前面,宽度为100%; 2). 左侧栏左浮动,默认情况下由于前面的元素宽度为100%,因此左侧栏是在中间栏下方,为左侧栏设置margin-left为-100%,即整个屏幕的宽度为100%,这就令左侧栏跑到中间栏的最左侧; 3). 右侧栏也是左浮动,此时默认情况下也是在中间栏下方一行的,同样利用margin-left: -300px,即自身的宽度,使其到上一行最右侧的位置; 4). 中间栏的内容部分则需要利用分别等于左右侧栏宽度的外边距来空出他们的位置
(3). 浮动定位法
*{ margin:0; padding:0; height:100%; } #left{ width:300px; background-color:yellow; float:left; } #right{ width:200px; background-color:orange; float:right; } #main{ background-color:aqua; margin-left:300px; margin-right:200px; } <!--左右侧栏的位置可以更改--> <div id="left"></div> <div id="right"></div> <!--中间栏放最后--> <div id="main"></div>
总结: 分别另左侧栏和右侧栏向左和向右浮动,中间栏放在最后,再利用左右外边距空出左右栏的位置即可
(4). flexbox
div{ display:-webkit-flex; display:flex; margin:0; padding:0; height:800px; } article{ flex:1 1; order:2; background-color:yellow; } nav{ flex:0 0 200px; order:1; background-color:blue; } aside{ flex:0 0 200px; order:3; background-color:aqua; } <div> <article></article> <nav></nav> <aside></aside> </div>
-
双飞翼布局
.header { width: 100%; height: 100px; background-color: red; } .content { overflow: hidden; } .footer { width: 100%; height: 100px; background-color: red; } .middle { width: 100%; float: left; } .inner-middle { width: 100%; margin: 0 100px; background-color: green; } .left { width: 100px; float: left; margin-left: -100%; background-color: yellow; } .right { width: 100px; float: left; margin-left: -100px; background-color: pink; } <div class="header"></div> <div class="content"> <div class="middle"> <div class="inner-middle"></div> </div> <div class="left"></div> <div class="right"></div> </div> <div class="footer"></div>
``` 总结: 跟圣杯布局没多大区别,就是middle的实现不一样,圣杯布局是middle+padding,双飞翼布局采用子元素+margin
-
圣杯布局
(1). flex
.container { display: flex; height: 600px; } .left { width: 500px; heihgt: 100%; background: blue; } .center { flex-grow: 1; height: 100%; background: gray; } .right { width: 150px; height: 100%; background: orange; } <div class="container"> <div class="middle"></div> <div class="left"></div> <div class="right"></div> </div>
(2). float
.container { padding:0 150px; outline: 1px dotted red; overflow: auto; } .center { float: left; width: 100%; height: 400px; background: gray; } .left { position: relative; margin-left: -100%; right:150px; float: left; width: 150px; height: 400px; background:blue; } .right { position: relative; float: left; margin-right: -150px; width: 150px; height: 400px; background: orange; } <div class="container"> <div class="center"></div> <div class="left"></div> <div class="right"></div> </div>
总结: 1). 先写middle,然后是left和right, 因为要先渲染middle; 2). left, right需设置position: relative以及相应的left, right值; 3). 负边距的作用, left的margin-left: -100%使它上移一行, 同时right向左移占据left原先位置,同理, right的margin-left: -100px使它上移并靠右
-
CSS实现一个自适应的正方形
.box { width: 200px; height: 200px; } CSS3 vw 单位,vw是相对于视口的宽度。视口被均分为100单位的vw。1vw = 1% viewport width .box{ width: 20%;//width:20vw也可以 height: 20vw; background: pink; } 设置盒子的padding-bottom样式,让盒子的padding-bottom和盒子的宽度一样,同时设置heigh = 0px; { width: 20%; /* 设置height为0 ,避免盒子被内容撑开多余的高度 */ height: 0px; /* 把盒子的高撑开, 和width设置同样的固定的宽度或者百分比 , 百分比相对的是父元素盒子的宽度 */ padding-bottom: 20% }
-
重排和重绘
1.HTML 被 HTML 解析器解析成 DOM 树; 2.CSS 被 CSS 解析器解析成 CSSOM 树; 3.结合 DOM 树和 CSSOM 树,生成一棵渲染树(Render Tree),这一过程称为 Attachment; 4.生成布局(flow),浏览器在屏幕上“画”出渲染树中的所有节点; 5.将布局绘制(paint)在屏幕上,显示出整个页面。 第四步和第五步是最耗时的部分,这两步合起来,就是我们通常所说的渲染。
重排: 当DOM的变化影响了元素的几何信息(元素的的位置和尺寸大小),浏览器需要重新计算元素的几何属性,将其安放在界面中的正确位置,这个过程叫做重排。
重排也叫回流,简单的说就是重新生成布局,重新排列元素。
页面初始渲染,这是开销最大的一次重排 添加/删除可见的DOM元素 改变元素位置 改变元素尺寸,比如边距、填充、边框、宽度和高度等 改变元素内容,比如文字数量,图片大小等 改变元素字体大小 改变浏览器窗口尺寸,比如resize事件发生时 激活CSS伪类(例如::hover) 设置 style 属性的值,因为通过设置style属性改变结点样式的话,每一次设置都会触发一次reflow 查询某些属性或调用某些计算方法:offsetWidth、offsetHeight等,除此之外,当我们调用 getComputedStyle方法,或者IE里的 currentStyle 时,也会触发重排,原理是一样的,都为求一个“即时性”和“准确性”。
重绘: 当一个元素的外观发生改变,但没有改变布局,重新把元素外观绘制出来的过程,叫做重绘。
如何减少重绘和重排
(1). C***transform代替top; 使用visibility替换display: none,因为前者只会引起重绘,后者会引发回流 避免使用table布局,可能很小的一个改动会造成整个table的重新布局 尽可能在DOM树的最末端改变class,回流是不可避免的,但是可以减少影响,尽可能在DOM树的最末端改变class,可以限制了回流的范围,使其影响尽可能少的节点; 将动画效果应用到position属性为absolute或fixed的元素上,避免影响其他元素的布局,这样只是一个重绘而不是回流 (2). JavaScript (1).避免频繁操作样式,最好一次性重写style属性,或者将样式列表定义为class并一次性更改class属性。 (2).避免频繁操作DOM,创建一个documentFragment,在它上面应用所有DOM操作,最后再把它添加到文档中。 (3).避免频繁读取会引发回流/重绘的属性,如果确实需要多次使用,就用一个变量缓存起来。 (4).对具有复杂动画的元素使用绝对定位,使它脱离文档流,否则会引起父元素及后续元素频繁回流。
-
script标签的async和defer的区别
都是提示浏览器先下载外部文件延迟执行,但是defer是顺序执行,async是乱序的只要保证两个文件之间互相不依赖
-
CSS实现一个扇形
.outer{ width:0; height:0; border-width:100px; border-style:solid; border-color: red transparent transparent transparent; border-radius:50%; }
-
img的title和alt属性
title: 全局属性 作用是提供建议性的信息,通常是鼠标滑动到元素上是显示 alt: 特有属性 图片内容的等价描述,用于图片无法加载时显示或读屏器阅读图片(帮助盲人了解图片内容)。可提图片高可访问性,除了纯装饰图片外都必须设置有意义的值,搜索引擎会重点分析。