1. CSS3 中新增了哪些新特性?
答:一些选择器、边框(border-radius
, border-image
)、box-shadow
、背景(background-origin``、``background-size
等)、文字(word-wrap
, text-overflow
, text-shadow
)、颜色(rgba
, hsla
)、transition
过渡、transform
转换(scale
缩放,translate
平移,rotate
旋转,skew
切斜)、animation
动画、渐变(linear-gradient
线性渐变和 radial-gradient
径向渐变)、Flex
布局、Grid
栅格布局、多列布局、媒体查询等等
2. CSS3 画一个三角形,其原理是什么?
我们有时候会需要用到一个三角形的形状,比如地址选择或者播放器里面播放按钮,通常情况下,我们会使用图片或者 svg 去完成三角形效果图
实心三角形
.border: { width: 0; height: 0; border-style: solid; border-width: 0 50px 50px; border-color: transparent transparent red; }
这时候就已经能够看到 4 个不同颜色的三角形,如果需要下方三角形,只需要将上、左、右边框设置为透明就可以得到下方的红色三角形. 但这种方式,虽然视觉上是实现了三角形,但实际上,隐藏的部分任然占据部分高度,需要将上方的宽度去掉
空心三角形(利用伪类)
伪类元素定位参照对象的内容区域宽高都为 0,则内容区域即可以理解成中心一点,所以伪元素相对中心这点定位
.border { width: 0; height: 0; border-style: solid; border-width: 0 50px 50px; border-color: transparent transparent #d9534f; position: relative; } .border:after { content: ''; border-style: solid; border-width: 0 40px 40px; border-color: transparent transparent #96ceb4; position: absolute; top: 6px; left: -40px; }
原理分析 采用的是均分原理:非常有意思的是盒子都是一个矩形或正方形,从形状的中心,向 4 个角上下左右划分 4 个部分
.square { width: 0; height: 0; margin: 0 auto; border-width: 6px; border-color: red transparent transparent transparent; border-style: solid dashed dashed dashed; // 为了兼容IE6,把没有的边框都设置为虚线 }
边框是实现三角形的部分,边框实际上并不是一个直线,如果我们将四条边设置不同的颜色,将边框逐渐放大,可以得到每条边框都是一个梯形.当分别取消边框的时候,发现下面几种情况:
- 取消一条边的时候,与这条边相邻的两条边的接触部分会变成直的
- 当仅有邻边时, 两个边会变成对分的三角
- 当保留边没有其他接触时,极限情况所有东西都会消失
通过上图的变化规则,利用旋转、隐藏,以及设置内容宽高等属性,就能够实现其他类型的三角形
/* 如设置直角三角形 */
.box {
/* 内部大小 */
width: 0px;
height: 0px;
/* 边框大小 只设置两条边*/
border-top: #4285f4 solid;
border-right: transparent solid;
border-width: 85px;
/* 其他设置 */
margin: 50px;
}
3. 获取元素的宽高的方式有哪些?
dom.style.width/height
原理:这种方式只能取到 dom 元素内联样式所设置的宽高;(也就是说如果该节点的样式是在 style 标签中或外联的 CSS 文件中设置的话,通过这种方法是获取不到 dom 的宽高的)
dom.currentStyle.width/height
原理:获取渲染后的宽高。(但仅 IE 支持)
dom.getComputedStyle(dom).width/height
原理:与 2 原理类似。但是兼容性,通用性更好一些
dom.getBoundingClientRect().width/height
原理:计算元素的绝对位置,获取到四个属性,left, top, right, bottom
4. 说说你对 盒子模型 的理解?
CSS3 中的盒模型有以下两种:标准盒模型、IE(怪异替代)盒模型。
两种盒子模型都是由 content + padding + border + margin 构成,其大小都是由 content + padding + border 决定的,但是盒子内容宽/高度(即 width/height)的计算范围根据盒模型的不同会有所不同:
- 标准盒模型:只包含 content
- IE(替代)盒模型:content + padding + border
可以通过 box-sizing 来改变元素的盒模型:
- box-sizing: content-box :标准盒模型(默认值)
- box-sizing: border-box :IE(替代)盒模型
5. CSS 中选择器有哪些?优先级?哪些属性可以继承?
样式的优先级一般为 !important
> style
> id
> class
> 标签选择器
优先级:
- !important
- 内联样式(1000)
- ID 选择器(0100)
- 类选择器/属性选择器/伪类选择器(0010)
- 元素选择器/伪元素选择器(0001)
- 关系选择器/通配符选择器(0000)
总结:带!important 标记的样式属性优先级最高; 样式表的来源相同时:!important > 行内样式>ID 选择器 > 类选择器 > 标签 > 通配符 > 继承 > 浏览器默认属性
css 属性选择器常用的有:
- id 选择器(#box),选择 id 为 box 的元素
- 类选择器(.one),选择类名为 one 的所有元素
- 标签选择器(div),选择标签为 div 的所有元素
- 后代选择器(#box div),选择 id 为 box 元素内部所有的 div 元素
- 子选择器(.one>one_1),选择父元素为.one 的所有.one_1 的元素
- 相邻同胞选择器(.one+.two),选择紧接在.one 之后的所有.two 元素
- 群组选择器(div,p),选择 div、p 的所有元素
- 通配符选择器(*)
一些使用频率相对不是很多的选择器:
- 伪类选择器(:link, :visited, :active, :hover)
- 伪元素选择器(:after, :before)
- 属性选择器([attribute], [attribute=value])
CSS3 中新增的选择器:
- 伪类选择器(:nth-child(n), :not, :last-child)
- 属性选择器([attribute^=value])
优先级是由 A 、B、C、D 的值来决定的,其中它们的值计算规则如下:
- 如果存在内联样式,那么 A = 1,否则 A = 0
- B 的值等于 ID 选择器(#id) 出现的次数
- C 的值等于 类选择器(.class) 和 属性选择器(a[href="https://example.org"]) 和 伪类(:first-child) 出现的总次数
- D 的值等于 标签选择器(h1,a,div) 和 伪元素(::before,::after) 出现的总次数
知道了优先级是如何计算之后,就来看看比较规则:
- 从左往右依次进行比较 ,较大者优先级更高
- 如果相等,则继续往右移动一位进行比较
- 如果 4 位全部相等,则后面的会覆盖前面的
CSS 属性继承 在 css 中,继承是指的是给父元素设置一些属性,后代元素会自动拥有这些属性
- 关于继承属性,可以分成:
字体系列属性
文本系列属性
元素可见性
表格布局属性
注意:继承中比较特殊的几点:
- a 标签的字体颜色不能被继承
- h1-h6 标签字体的大小也是不能被继承的
- 无继承的属性:
- display
- 文本属性:vertical-align、text-decoration
- 盒子模型的属性:宽度、高度、内外边距、边框等
- 背景属性:背景图片、颜色、位置等
- 定位属性:浮动、清除浮动、定位 position 等
- 生成内容属性:content、counter-reset、counter-increment
- 页面样式属性:size、page-break-before、page-break-after
扩展:CSS 伪类用于向某些选择器添加特殊的效果。CSS 伪元素用于向某些选择器设置特殊效果。
6. display 和 position 有哪些值?
display
的值:none、inline、inline-block、block、table、flexposition
的值:static、relative、absolute、fixed、inherit、sticky- static(没有定位)是 position 的默认值,元素处于正常的文档流中,会忽略 left、top、right、bottom 和 z-index 属性。
- relative(相对定位)是指给元素设置相对于原本位置的定位,元素并不脱离文档流,因此元素原本的位置会被保留,其他的元素位置不会受到影响。
- absolute(绝对定位)是指给元素设置绝对的定位,相对定位的对象可以分为两种情况:
- 设置了 absolute 的元素如果存在有祖先元素设置了 position 属性为 relative 或者 absolute,则这时元素的定位对象为此已设置 position 属性的祖先元素。
- 如果并没有设置了 position 属性的祖先元素,则此时相对于 body 进行定位。
- fixed 可以简单说 fixed 是特殊版的 absolute,fixed 元素总是相对于 body 定位的。
- inherit 继承父元素的 position 属性,但需要注意的是 IE8 以及往前的版本都不支持 inherit 属性。
扩展补充:display: none
、visibility: hidden
和 opacity: 0
之间的区别?
- 相同点:都是隐藏
- 不同点:
是否占据空间
display: none
, 隐藏之后不占
据空间visibility: hidden
、opacity: 0
隐藏后任然占据
空间
子元素是否继承
display: none
, 不会被子元素继承,父元素都不存在了,子元素也不会显示visibility: hidden
, 会被子元素继承,通过设置子元素,visibility: visible
来显示子元素opacity: 0
, 会被子元素继承,但是不能设置子元素opacity
来重新显示
事件绑定
display: none
, 元素都不在了,所以无法触发它绑定的事件visibility: hidden
, 不会触发它上面绑定的事件opacity: 0
, 元素上面绑定的事件是可以触发的
过渡动画
transition
: 对于display
是无效的
transition
: 对于visibility
是无效的
transition
: 对于 opacity 是有效的
7. 清除浮动的方式有哪些?
- 方式一、添加额外标签,使用 clear:both;清除浮动
<div class="parent"> <!-- 添加额外标签并且添加clear属性 --> <div style="clear:both"></div> <!-- 也可以加一个br标签 --> </div>
- 方式二、利用伪元素:after 来清除浮动
// 在css中添加:after伪元素 .parent:after { /* 设置添加子元素的内容是空 */ content: ''; /* 设置添加子元素为块级元素 */ display: block; /* 设置添加的子元素的高度0 */ height: 0; /* 设置添加子元素看不见 */ visibility: hidden; /* 设置clear:both */ clear: both; }
- 方式三、使用 CSS 的 overflow 属性(BFC)
8. 说说重绘 & 重排?
简单地总结下两者的概念:
- 重排:无论通过什么方式影响了元素的几何信息(元素在视口内的位置和尺寸大小),浏览器需要重新计算元素在视口内的几何属性,这个过程叫做重排
- 重绘:通过构造渲染树和重排(回流)阶段,我们知道了哪些节点是可见的,以及可见节点的样式和具体的几何信息(元素在视口内的位置和尺寸大小),接下来就可以将渲染树的每个节点都转换为屏幕上的实际像素,这个阶段就叫做重绘
如何减少重排和重绘?
- 最小化重绘和重排,比如样式集中改变,使用添加新样式类名 .class 或 cssText
- 批量操作 DOM,比如读取某元素 offsetWidth 属性存到一个临时变量,再去使用,而不是频繁使用这个计算属性;又比如利用 document.createDocumentFragment() 来添加要被添加的节点,处理完之后再插入到实际 DOM 中
- 使用 absolute 或 fixed 使元素脱离文档流,这在制作复杂的动画时对性能的影响比较明显
- 开启 GPU 加速,利用 css 属性 transform 、will-change 等,比如改变元素位置,我们使用 translate 会比使用绝对定位改变其 left 、top 等来的高效,因为它不会触发重排或重绘,transform 使浏览器为元素创建⼀个 GPU 图层,这使得动画元素在一个独立的层中进行渲染。当元素的内容没有发生改变,就没有必要进行重绘
扩展:transform
会造成回流吗?
渲染流水线是这样的顺序:重排 -> 重绘 -> 合成
;transform: translate
是直接合成,跳过了前面的重排重绘。但是 限制高宽也会出现问题,譬如图片被拉伸了。
-> 给 <img/>
标签写上宽高,可以在图片未加载之前提前占住位置,避免图片从未加载状态到渲染完成状态高宽变化引起的 重排 问题。object-fit: cover
,它能够指定可替换元素的内容(也就是图片)该如何适应它的父容器的高宽。object-fit 还有一个配套属性 object-position,它可以控制图片在其内容框中的位置。(类似于 background-position),m 默认是 object-position: 50% 50%,如果你不希望图片居中展示,可以使用它去改变图片实际展示的 position 。
img {
width: 100px;
height: 100px;
object-fit: cover;
object-position: 50% 50%;
}
9. defer、async 的区别?
script
:会阻碍HTML
解析,只有下载好并执行完脚本才会继续解析 HTML。async script
:解析HTML
过程中进行脚本的异步下载,下载成功立马执行,有可能会阻断 HTML 的解析。defer script
:完全不会阻碍HTML
的解析,解析完成之后再按照顺序执行脚本。
10. 说说 html、css、js 的加载顺序?
html
解析 -> htmlParser2
css
解析 -> css
- DOM 解析:把所写的各种
html
标签,生成一个DOM TREE
,相当于是生成了一个最原始的页面,一点样式都没有,毫无CSS
修饰。边解析边渲染 - DOM 渲染:浏览器会把本身默认的样式 + 用户自己写得样式整合到一起,形成一个
CSS TREE
,而DOM
渲染就是指DOM TREE
和CSS TREE
结合到一起,生成一个Render TREE
,呈现出一个带有样式的页面 DOM
与CSS
css
的加载不会阻塞DOM
的解析css
的加载会阻塞DOM
的渲染
DOM
与JS
JS
(加载和执行) 都会阻塞DOM
的解析JS
(加载和执行) 都会阻塞DOM
的渲染
注:html
中每遇到 script
标签,页面就会重新渲染一次,因为要保证标签中的 JS
代码拿到的都是最新的样式
CSS
与JS
CSS
的加载阻塞JS
的运行,不阻塞JS
的加载。CSS
和JS
同时加载
注:CSS
的渲染 GUI 线程
和 JS 运行线程
互斥
总结:
script
最好放底部,link
最好放头部。注意:link
放到底部,可能会发生重绘
,因为渲染DOM
,要等待样式加载完毕如果头部同时有
script
与link
的情况下,最好将script
放在link
上面HTML
在加载的时候,会预先加载CSS
和JS
,且并行加载。JS
阻塞DOM
解析 和 渲染。JS
要等上面的的css
加载完毕,保证页面可以操作样式 扩展:为了避免让用户看到长时间的白屏时间,我们应该尽可能的提高css
加载速度,比如可以使用以下几种方法:使用
CDN
(因为CDN
会根据你的网络状况,替你挑选最近的一个具有缓存内容的节点为你提供资源,因此可以减少加载时间)对
css
进行压缩(可以用很多打包工具,比如webpack
,gulp
等,也可以通过开启 gzip 压缩)合理的使用缓存(设置
cache-control
,expires
,以及E-tag
都是不错的,不过要注意一个问题,就是文件更新后,你要避免缓存而带来的影响。其中一个解决防范是在文件名字后面加一个版本号)减少
http
请求数,将多个css
文件合并,或者是干脆直接写成内联样式(内联样式的一个缺点就是不能缓存)不要在嵌入的
JS
中调用运行时间较长的函数,如果一定要用,可以用setTimeout
来调用
- 扩展:
DOM
如何生成的?- 在解析前会执行
预解析
操作,会预先加载JS
、CSS
等文件 - 字节流 -> 分词器 -> 根据 token 生成节点 -> 插入到
DOM 树
中 - 遇到
JS
:在解析过程中遇到script
标签,HTMLParser
会停止解析,(下载)执行对应的脚本 - 在
JS
执行前,需要等待当前脚本之上的所有CSS
加载解析完毕(JS
是依赖CSS
的加载)
- 在解析前会执行
11. 你知道哪几种方式可以隐藏一个元素?
答:opacity/filter: opacity()
、clip-path
、position
、z-index
、visibility
、覆盖一个元素(伪类:after)
、display
、transform: scale(0)/translate(-999px, 0px)
、color alpha
、缩小尺寸
等
12. 了解 H5 的 draggable 拖拽吗?
为了使元素可拖动,把 draggable
属性设置为 true
。draggable
属性可用于任何元素节点,但是图片(img
)和链接(a
)不加这个属性,就可以拖拉
注意:一旦某个元素节点的 draggable
属性设为 true
,就无法再用鼠标选中该节点内部的文字或子节点了
- 当元素节点或选中的文本被拖拉时,包括以下一些事件:
drag
:拖拉过程中dragstart
:用户开始拖拉时dragend
:拖拉结束时dragenter
:拖拉进入当前节点时dragover
:拖拉到当前节点上方时dragleave
:拖拉操作离开当前节点范围时drop
:被拖拉的节点或选中的文本,释放到目标节点时
13. 优化长列表滚动效果?
transition 优化动画效果,分层渲染
- 第一种、用 transform 进行强制分层
- 第二种、可以用 content-visibility 将看不见的元素不渲染,设置值为 auto 即可
- 第三种、是对于某些动画效果,可以用 will-change 作用在父元素上进行 gpu 加速,使用后删掉
- 第四种、懒加载:即监听 scroll 事件或使用 IntersectionObserver 监听
- 第五种、可视区域渲染: 仅在可视区域展示数据,为保证滚动条的完整性,非可视区域使用占位元素的高度后者容器的位移来撑开。
扩展:css 怎么开启硬件加速(GPU 加速)
- transform(当 3D 变换的样式出现时会使用 GPU 加速)
- opacity
- filter
- will-change
浏览器在处理上面的 css 的时候,会使用 GPU 渲染
14. 移动端 1px 像素如何解决?
在 CSS 规范中,长度单位可以分为两类,绝对(absolute)单位以及相对(relative)单位。px 是一个相对单位,相对的是设备像素(device pixel)。
- PX(CSS pixels)虚拟像素,可以理解为“直觉”像素,CSS 和 JS 使用的抽象单位,浏览器内的一切长度都是以 CSS 像素为单位的,CSS 像素的单位是 px。
- DP(device pixels)设备像素(物理像素),顾名思义,显示屏是由一个个物理像素点组成的,通过控制每个像素点的颜色,使屏幕显示出不同的图像,屏幕从工厂出来那天起,它上面的物理像素点就固定不变了,单位 pt。 pt 在 css 单位中属于真正的绝对单位,1pt = 1/72(inch),inch 及英寸,而 1 英寸等于 2.54 厘米。
- DPR(device pixels ratio)DPR = 设备像素/CSS 像素
- DIP(Device independent Pixel)设备独立像素/逻辑像素.可以理解为: 设备独立像素 = css 像素
根本原因:因为不同设备可能有不同的 dpr,导致了 1px 展示的宽度有所不同。
问题
- 问:1px 的设置是没有问题的,那么是什么导致了不同设备的表现不一致呢? 答: 不同的 dpr 导致了不同设备的 1px 包含了不同数量的 pt
- 问:我和设计小伙伴嘴里说的 1px 是一个东西吗? 答:并不是,设计小伙伴真正想要的是 1pt 的效果
解决方案
注意:我在两倍屏把宽度定义成 0.5px 不就行了吗?0.5px 也只在 ios8+上支持(小于 ios8 被转为 0px),安卓上是不行的。
方式一、background-image && border-image
.background-image-1px { background: url(...) no-repeat left bottom; -webkit-background-size: 100% 1px; background-size: 100% 1px; } .border-bottom-1px { border-width: 0 0 1px 0; -webkit-border-image: url(...) 0 0 2 0 stretch; border-image: url(...) 0 0 2 0 stretch; }
优势: 至少解决了问题
劣势: 我想换个颜色还得换图,而且图片处理圆角会出现模糊的问题
方式二、border-shadow
通过 css 对 border-shadow 的处理来模拟 0.5px
.box-shadow-1px { box-shadow: inset 0px -1px 1px -1px #c8c7cc; }
优势: 代码少,还能换颜色
劣势: 阴影导致的颜色变浅,而且仔细看谁都看得出这是阴影而不是边框
方式三、伪元素 + scale 缩放
构建 1 个伪元素, border 为 1px, 再以 transform 缩放到 50%。ant-design-mobile 同样使用这种处理
原理: 是把原先元素的 border 去掉,然后利用 :before 或者 :after 重做 border ,并将 transform 的 scale 缩小一半,原先的元素相对定位,新做的 border 绝对定位。
.scale-1px { position: relative; border: none; } .scale-1px:after { content: ''; position: absolute; bottom: 0; background: #000; width: 100%; height: 1px; -webkit-transform: scaleY(0.5); transform: scaleY(0.5); -webkit-transform-origin: 0 0; transform-origin: 0 0; }
四条 border 样式设置:
.scale-1px { position: relative; margin-bottom: 20px; border: none; } .scale-1px:after { content: ''; position: absolute; top: 0; left: 0; border: 1px solid #000; -webkit-box-sizing: border-box; box-sizing: border-box; width: 200%; height: 200%; -webkit-transform: scale(0.5); transform: scale(0.5); -webkit-transform-origin: left top; transform-origin: left top; }
最好在使用前也判断一下,结合 JS 代码,判断是否 Retina 屏:
if (window.devicePixelRatio && devicePixelRatio >= 2) { document.querySelector('ul').className = 'scale-1px' }
优点:可以满足所有场景,且修改灵活。缺点:对于已使用伪类的元素(例如 clearfix)要多层嵌套。
方式四、viewport + rem 实现
同时通过设置对应 viewport 的 rem 基准值,这种方式就可以像以前一样轻松愉快的写 1px 了。 在 devicePixelRatio = 2 时,输出 viewport:
<meta name="viewport" content="initial-scale=0.5, maximum-scale=0.5, minimum-scale=0, user-scalable=no" />
在 devicePixelRatio = 3 时,输出 viewport:
<meta name="viewport" content="initial-scale=0.3333333333333333, maximum-scale=0.3333333333333333, minimum-scale=0.3333333333333333, user-scalable=no" />
优点:所有场景都能满足。一套代码,可以兼容基本所有布局 缺点:老项目修改代价过大,只适用于新项目
15. css 如何实现一个正方形盒子(随父元素)自适应?
- 方式一、CSS3 vw 单位,vw 是相对于视口的宽度。视口被均分为 100 单位的 vw。1vw = 1% viewport width
.box { width: 20%; // 20vw也可以 height: 20vw; background: red; }
- 方式二、设置盒子的 padding-bottom 样式,让盒子的 padding-bottom 和盒子的宽度一样,同时设置 heigh = 0px;盒子设置了 heigh:0px;导致该元素里面再有子元素的时候,就无法正常设置高度。所以我们需要用到 position: absolute;使当前内容脱离文档流,那么内容的高度百分比参照的就是父级的宽度
.box { width: 20%; /* 设置height为0,避免当盒子里面有内容的时候,盒子会被内容撑大 */ height: 0px; /* 把盒子的高撑开,和width设置同样的固定的宽度或者百分比。百分比相对的是父元素盒子的宽度 */ padding-bottom: 20%; background: red; }
经典 Flex 布局
如今Flex
布局不管是移动端还是 PC 端的应用已经非常广泛了,下面我列举几个平时项目中非常常见的几个需求。以下例子我们都以 Vue 项目为例~
flex 布局均匀分布后换行问题
需求一:ul
下有多个li
,每三个li
排一列,多余的换行显示。
很显然,绝大部分的小伙伴都会使用Flex布局
,很显然会出现一个问题就是如果 li 是 3 的倍数的话就能正常显示,若不是的话,布局就不是产品经理满意的结果。
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
解决方案:
我们在ul
的底部新增li
,个数为数组总长度%3的余数即可。
<li class="item" style="border: none;" v-for="(ite, idx) in list.length%3" :key="idx"></li>
扩展:
flex:1
是哪些属性组成的
flex
实际上是 flex-grow
、flex-shrink
和 flex-basis
三个属性的缩写
flex-grow
:定义项目的的放大比例默认为 0,即 即使存在剩余空间,也不会放大;所有项目的 flex-grow 为 1:等分剩余空间(自动放大占位);flex-grow 为 n 的项目,占据的空间(放大的比例)是 flex-grow 为 1 的 n 倍。
flex-shrink
:定义项目的缩小比例默认为 1,即 如果空间不足,该项目将缩小;所有项目的 flex-shrink 为 1:当空间不足时,缩小的比例相同;flex-shrink 为 0:空间不足时,该项目不会缩小;flex-shrink 为 n 的项目,空间不足时缩小的比例是 flex-shrink 为 1 的 n 倍。
flex-basis
: 定义在分配多余空间之前,项目占据的主轴空间(main size
),浏览器根据此属性计算主轴是否有多余空间默认值为 auto,即 项目原本大小;设置后项目将占据固定空间。
两栏布局
两栏布局:
左右两栏,左边固定,右边自适应
效果图
第一种方式 ---
浮动
HTML 部分:
<div class="outer outer1"> <div class="left">1-left</div> <div class="right">1-right</div> </div>
CSS 部分:
.outer1 .left { width: 200px; float: left; } .outer1 .right { width: auto; margin-left: 200px; }
第二种方式 ---
flex
HTML 部分:
<div class="outer outer2"> <div class="left">2-left</div> <div class="right">2-right</div> </div>
CSS 部分:
.outer2 { display: flex; } .outer2 .left { flex: 0 0 200px; /* flex-grow: 0; flex-shrink:0; flex-basis:200px; */ } .outer2 .right { flex: auto; } 注意:flex: 0 0 200px是flex: flex-grow flex-shrink flex-basis的简写
第三种方式 ---
position
HTML 部分:
<div class="outer outer3"> <div class="left">3-left</div> <div class="right">3-right</div> </div>
CSS 部分:
.outer3 { position: relative; } .outer3 .left { position: absolute; width: 200px; } .outer3 .right { margin-left: 200px; }
第四种方式 ---
position again
HTML 部分:
<div class="outer outer4"> <div class="left">4-left</div> <div class="right">4-right</div> </div>
CSS 部分:
.outer4 { position: relative; } .outer4 .left { width: 200px; } .outer4 .right { position: absolute; top: 0; left: 200px; right: 0; }
三栏布局
三栏布局:
中间列自适应宽度,旁边两侧固定宽度
效果图
第一种方式 ---
定位
HTML 部分:
<div class="outer outer1"> <div class="left">1-left</div> <div class="middle">1-middle</div> <div class="right">1-right</div> </div>
CSS 部分:
.outer1 { position: relative; } .outer1 .left { position: absolute; width: 100px; } .outer1 .middle { margin: 0 200px 0 100px; } .outer1 .right { position: absolute; width: 200px; top: 0; right: 0; } 注意:左右分别使用绝对定位,中间设置外边距
第二种方式 ---
flex布局
HTML 部分:
<div class="outer outer2"> <div class="left">2-left</div> <div class="middle">2-middle</div> <div class="right">2-right</div> </div>
CSS 部分:
.outer2 { display: flex; } .outer2 .left { flex: 0 0 100px; } .outer2 .middle { flex: auto; } .outer2 .right { flex: 0 0 200px; }
第三种方式 ---
浮动原理
HTML 部分:
<div class="outer outer3"> <div class="left">3-left</div> <div class="right">3-right</div> <div class="middle">3-middle</div> </div>
CSS 部分:
.outer3 .left{ float: left; width: 100px; } .outer3 .right { float: right; width: 200px; } .outer3 .middle { margin: 0 200px 0 100px; }
圣杯布局
圣杯布局:
中间的优先渲染,独立的左中右结构
具体实现圣杯布局的步骤:
- 让左右浮动在一行显示,相对定位
- 让中间模块的 middle 宽度为 100%
- 让左边的色块移动到 middle 前面,margin-left:-100%
- 让右边的色块移动到 middle 的后面,margin-left:-宽度
- 给三个小块的父元素加一个内填充的属性 padding,为的是填充挤到中间
- 给左边的块移动到左边 left:-200px, 给右边的块移动到右边 right:-200px
效果图
HTML 部分:
<header>header</header>
<div class="container">
<div class="middle">midlle</div>
<div class="left">left</div>
<div class="right">right</div>
</div>
<footer>footer</footer>
CSS 部分:
header, footer {
height: 100px;
width: 100%;
background-color: antiquewhite;
}
.container {
height: 200px;
padding-left: 200px;
padding-right: 300px;
}
.container > div {
float: left;
position: relative;
height: 100%;
}
.left {
width: 200px;
height: 200px;
background-color: burlywood;
margin-left: -100%;
left: -200px;
}
.right {
width: 300px;
height: 200px;
background-color: burlywood;
margin-left: -300px;
right: -300px;
}
.middle {
width: 100%;
height: 200px;
background-color: #b0f9c2;
}
双飞翼布局
双飞翼布局
具体实现双飞翼布局的步骤:
- 给左,中,右 加浮动,在一行显示
- 给 middle 宽度为 100%
- 让左边的模块移动 middle 的左边 margin-left:-100%
- 让右边的模块移动 middle 的右边 margin-left:-自己宽度
- 给 middle 里面的容器添加外间距 margin: 左右
效果:
html 部分
<div class="main">
<div class="middle">
<div class="middle-inner">中间</div>
</div>
<div class="left">左边</div>
<div class="right">右边</div>
</div>
css 部分
.main>div {
float:left;
position: relative;
height: 300px;
}
.middle {
width: 100%;
background-color: lightgreen
}
.left {
width:200px;
margin-left:-100%;
background-color:#b0f9c2
}
.right {
width: 200px;
margin-left:-200px;
background-color:pink
}
.middle-inner{
margin:0 200px;
background-color: burlywood;
height:300px;
}
水平垂直居中
html 部分
<div class="box" id="box">
石小明
</div>
css 部分
公共部分
body {
width: 100vw;
height: 100vh;
overflow: hidden;
}
.box {
box-sizing: border-box;
width: 100px;
height: 50px;
line-height: 50px;
text-align: center;
font-size: 16px;
border: 1px solid lightblue;
background: lightcyan;
}
第一种:定位
.box {
position: absolute;
top: 50%;
left: 50%;
margin-left: -50px;
margin-top: -25px;
}
注意:上面的方式是一定要知道具体的宽高。但下面的方式是知道宽高,但是没有用到宽高。
第二种:flex
body {
display: flex;
justify-content: center;
align-items: center;
}
注意:这种方式也是兼容性不是很好
第三种:JavaScript
let html = document.documentElement,
winW = html.clientWidth,
winH = html.clientHeight,
boxW = box.offsetWidth, // offsetWidth带边框
boxH = box.offsetHeight;
box.style.position = 'absolute';
box.style.left = (winW - boxW) / 2 + 'px';
box.style.top = (winH - boxH) / 2 + 'px';
第四种:table-cell
body {
display: table-cell;
vertical-align: middle;
text-align: center;
}