盒子模型
盒子模型:
box-sizing
,描述了文档中的元素如何生成矩形盒子,并通过这些盒子的布局来组织和设计网页。包含content、padding、margin、border四个部分。
分类
- W3C盒子模型(
content-box
):标准盒子模型,Width = width - IE盒子模型(
border-box
):Width = width + padding + border
BFC
BFC:块级上格式下文,是一块具有自己渲染规则的渲染区域。
渲染规则:
- 内部盒子垂直向上一个接一个堆叠
- 同一个BFC的两个相邻盒子的
margin
会重叠- BFC的区域不会与
float
元素区域重叠- 计算BFC的高度时,浮动子元素也参与计算
- 每个元素的左外边距与包含块的左边界相接触;
-BFC就是一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然。
BFC的触发条件
触发BFC的条件包含但不局限于:
- 根元素
- 浮动元素:
left
、right
overflow
的值除了visible
外display
的值为inline-
、flex-
等;position
的值为absolute
或fixed
BFC应用场景
- 防止
margin
塌陷 - 清除内部浮动
- 自适应多栏布局
响应式设计
特点
- 同时适配PC + 平板 + 手机等;
- 根据视口调整模块大小和位置
实现方式
响应式设计的基本原理是通过媒体查询检测不同的设备屏幕尺寸做处理。为了处理移动端,页面头部必须有meta
声明viewport
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"></meta>
实现方式:
- 媒体查询:
@media screen and (max-width: 1920px) {...}
- 百分比:height、width属性的百分比依托父元素的宽高,但是其它属性不完全依赖;
- vw/vh:相对于视图窗口的宽高;
- rem:相对于根元素
html
的font-size
属性,默认情况下浏览器大小为16px
,此时,1rem = 16px
元素的水平垂直居中方法
实现方式:
- 定位 +
margin: auto
- 定位 +
margin: 负值
- 定位 +
transform
- table布局
- flex布局
- grid布局:网格布局
多栏布局、剩余宽度自适应
两栏布局
两栏布局一般是一个定宽栏和一个自适应的栏并排展示存在。
实现思路:
float
左浮左边栏- 右边模块使用
margin-left
撑出内容块做内容展示 - 为父级元素添加BFC,防止下方元素飞向上
.box {
overflow: hidden;
}
.left {
width: 200px;
flot: left;
height: 100%;
}
.right {
margin-left: 200px;
height: 100%;
}
三栏布局
实现思路:
- 两边固定宽度、
float
,中间使用margin
- 两边定宽、使用
absolute
,中间使用margin
- 两边使用
float
和负margin
- flex实现
弹性布局
- flex-direction
- flex-wrap
- flex-flow: flex-direction flex-wrap;
- justify-content
- align-items:定义项目在交叉轴上如何对齐
- align-content:定义多根轴线的对齐方式。
- order:项目的排列顺序,数值越小,排列越靠前,默认为0
- flex-grow:定义项目的放大比例,默认为0,即存在剩余空间也不放大;
- flex-shrink:定义项目的缩放比例
- flex-basis:设置元素在主轴上的初始尺寸,默认为内容决定;
- align-self:单个项目的对齐方式
CSS选择器
分类:
- id选择器
- 类选择器
- 标签选择器
- 后代选择器(
div p
) - 子选择器(
div > p
) - 相邻同胞选择器(
div + p
) - 群组选择器(div, p)
- 伪类选择器:(
first-child
、:nth-child()
等) - 属性选择器(
[attribute~=value]
等) - 层次选择器(
p~ul
:选择前面有p元素的每个ul)
实现单行/多行文本溢出的省略样式
- 单行文本溢出省略
<style>
.text-ellipsis {
overflow: hidden;
line-height: 40px;
height: 40px;
width: 100%;
text-overflow: ellipsis;
white-space: nowrap; /*文本不换行*/
}
</style>
- 多行文本溢出省略
- 基于高度截断:伪元素+定位
<style>
.text-ellipsis1 {
position: relative;
line-height: 20px;
height: 40px;
overflow: hidden;
word-break: break-all;
}
.text-ellipsis1:after {
content: '...';
position: absolute;
bottom: 0px;
right: 0px;
padding: 0 20px 0 10px;
}
</style>
- 基于行数截断(
-webkit-box-clamp
):
<style>
.text-ellipsis2 {
width:100%;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
text-overflow: ellipsis;
}
</style>
CSS 实现一个三角形
<style>
.border {
width: 0;
height: 0;
border-style: solid;
border-width: 0 50px 50px;
border-color: transparent transparent #ff0000;
}
</style>
CSS3 动画
transition
实现渐变动画:transition: all 2s ease-in 500ms;
transform
转变动画:scale
、translate
、rotate
、skew
animation
实现自定义动画:通过@keyframes
来定义关键帧
<style>
@keyframes rotate {
from {
transform: rotate(0deg)
}
to {
transform: rotate(180deg)
}
}
div {
animation: rotate 2s;
}
</style>
CSS的设备像素、css像素、设备独立像素、dpr、ppi
css像素
逻辑像素**:也称为CSS像素,设备独立像素DIP,是一种虚拟的像素单位,用于设备元素在设备上的真实风格。一个逻辑像素可以对应多个物理像素。
css像素以px
为后缀,是一个长度单位,是一种相对单位,相对的是设备像素。
一般情况,页面缩放比为1,1个css像素 = 1个设备独立像素。
px
会受到下面的因素的影响而变化:
- 每英寸像素(PPI)
- 设备像素比(DPR)
设备像素(物理像素)
物理像素:是设备屏幕实际拥有的最小单位,这些像素点是真实存在的,决定了屏幕的分辨率和显示质量。固定不变,单位为pt
。
设备独立像素
设备独立像素,与设备无关的逻辑像素,代表可以通过程序控制使用的虚拟像素,是一个总体概念。
一个设备独立像素里可能包含一个或者多个物理像素点,包含的越多则屏幕看起来越清晰。
至于1个虚拟像素被换算成几个物理像素,这个数值就成为设备像素比(DPR)。
设备像素比(DPR)
DPR = 设备像素 / 设备独立像素,在window中通过window.devicePixelRatio
获取。
总结
- 无缩放情况下,1个css像素 = 1个设备独立像素;
- 设备像素由屏幕生成之后确定,不变;
- PC中,1个设备独立像素 = 1个设备像素(未缩放情况下);
- 移动端中,标准屏幕(160ppi)下,1个设备独立像素 = 1个设备像素;
- 设备像素比(dpr) = 设备像素 / 设备独立像素;
- 每英寸像素(ppi),值越大越清晰
px、em、rem、vh、vw
-
px:绝对单位,大小与元素的其它属性无关;
-
em:相对长度单位,相对于当前对象内文本的字体尺寸,特点
- em的值不固定;
- em会继承父级元素的字体大小;
- em是相对单位,相对于当前对象内文本的字体尺寸;
- 任意浏览器的默认字体高都是16px(1em = 16px);
- 为了简化
font-size
的计算,我们只需要配置body的font-size: 62.5%;
即可,此时:1em = 10px。
-
rem:相对单位,相对HTML根元素的
font-size
的值。
Chrome支持12px
解决方案:
- zoom: 0.8;
- -webkit-transform: scale()
- -webkit-text-size-adjust: none;
回流和重绘
回流:布局引擎根据各种样式计算每个盒子在页面上的大小和位置;在页面初始渲染阶段,会留不可避免的会触发。
重绘:当计算好盒模型的位置、大小和其它属性后,浏览器会根据每个盒子的特性进行绘制。
触发回流一定会触发重绘。回流的阶段主要是计算节点的位置和集合信息,当页面布局或者几何信息发生变化,则需要回流。重绘的阶段主要是做样式修改渲染。
如何减少回流
- 样式组合
- 避免内联样式使用
- 复杂的动画应尽可能脱离文档流;
- 使用css3硬件加速,transform等动画不会引起回流重绘;
- 等;
css预编译语言
css提高性能的方法有哪些?
- 内联首屏关键css
- 异步加载css
- 资源压缩
- 合理使用选择器
- 不要使用
@import
:会影响浏览器的并行下载,是的页面夹杂延迟 - 把小的icon图片转base64编码使用等
移动端适配、兼容问题
适配
目前主流的IOS设备主要有iPhone SE(4英寸)、iPhone6s/8E(4.7英寸)等,都是采用了Retina视网膜屏幕,其中,iPhone 6s/7/8 Plus 和 iPhone X 采用的是3倍率的分辨率,其他都是采用的2倍率的分辨率,无论是栏高度还是应用图标,设计师提供给开发人员的切片大小,前者始终是后者的1.5倍,并分别以@3x和@2x在文件名结尾命名,程序再根据不同分辨率自动加载@3x或者@2x的切片。
设计适配
一般情况下,选择中间尺寸750 * 1134作为基准,向上和向下适配。
兼容问题
-
ios端兼容input光标高度
描述:input输入框,在安卓上没问题,但是IOS上点击输入,光标高度等于父盒子高度(过长)。这是由于通常我们用
height
属性设置行间的高度和line-height
设置行间的距离,当点击输入的时候,光标的高度就自动与父盒子保持一致了。
解决办法
高度height
和line-height
内容用padding
撑开。 -
ios端微信h5页面上下滑动时卡顿、页面缺失
描述:在ios端,上下滑动页面是,如果页面高度超出了一屏,就会出现明显的卡顿,页面有部分内容显示不全的情况。这是由于按住奥使用的是webkit内核,ios使用的是Safari内核,Safari对于
over-scrolling
用了原生空间来实现。对于有webkit-over-scrolling
的网页,会创建一个UIScrollView,提供子layer给渲染模块使用。
解决办法
在公共样式中,添加* {-webkit-over-scrolling: touch}
即可。 -
IOS键盘唤起,键盘收起以后页面不归位
描述:输入呢你人,软键盘弹出,页面内容整体上移,但是键盘收起,页面内容不下滑。这是由于固定定位的元素,在元素内input框聚焦的时候,弹出的软键盘占位,失去焦点的时候软键盘小时,但是还是占位的。导致input框不能再次输入。
position: fixed
的元素在ios里,收起键盘的时候会被顶上去,特别是第三方键盘
解决办法
<div class="list-warp">
<divclass="title">
<span>投·被保险人姓名</span>
</div>
<divclass="content">
<input class="content-input"placeholder="请输入姓名"v-model="peopleList.name" @focus="changefocus()" @blur.prevent="changeBlur()"/>
</div>
</div>
changeBlur(){
let u = navigator.userAgent, app = navigator.appVersion;
let isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
if(isIOS){
setTimeout(() => {
const scrollHeight = document.documentElement.scrollTop || document.body.scrollTop || 0
window.scrollTo(0, Math.max(scrollHeight - 1, 0)) }, 200
)}
}
}
-
安卓弹出的键盘遮盖文本框
描述:安卓微信H5弹出软键盘后遮挡住input框。
解决办法
给input 和 textarea标签添加focus事件。判断安卓机型操作下,延迟0.5s,将输入框滚动至可视区域内(如果已经滚动到底部了,则无法再展示) -
Vue中路由使用hash模式,开发微信H5页面分享时,安卓上设置分享成功,但是ios分享异常
描述:ios当前页分享给好友,点进去是正常的,如果二次分享,则跳转至首页;使用Vue router跳转到第二个页面后再分享时,分享设置失败。这是由于js sdk是后端进行签署,前端校验,但是貌似系统不一样,传参内容也不一样,每次获取URL并不能获取到这些参数。解决办法
使用window.location.href
跳转,代替VueRouter跳转方法。