关键词:FAQ 飞行手册
绝对定位元素与非绝对定位元素的宽高百分比计算的区别
绝对定位: 宽高百分比相对于临近的 position 不为 static 的祖先元素的 PaddingBox 计算。
非绝对定位元素: 宽高百分比相对于父元素的 ContentBox 计算。
style 标签写在 body 后与 body 前有什么区别?
写在 body 后会出现页面闪烁问题。
首先页面加载自上而下,写在body标签后由于浏览器以逐行方式对HTML文档进行解析,当解析到写在尾部的样式表(外联或写在style标签)会导致浏览器停止之前的渲染,等待加载且解析样式表完成之后重新渲染。
如何水平垂直居中
水平垂直居中
- 绝对定位(margin/transform/inline-block)
- flex
- grid
/* margin auto 方法 */
div {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
/* 固定宽高 */
width: 300px;
height: 300px;
margin: auto;
}
/* margin 宽高一半 或者 translate */
div {
position: absolute;
width: 500px;
height: 300px;
top: 50%;
left: 50%;
/*外边距为自身宽高的一半*/
margin: -150px -250px;
/* 或者 利用 translate */
/* transform: translate(-50%, -50%); */
}
/* text-align 方法 */
.wrap {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
text-align: center;
vertical-align: middle;
}
.wrap::after {
content: '';
display: inline-block;
height: 100%;
vertical-align: middle;
}
.box {
display: inline-block;
width: 500px;
height: 400px;
background-color: pink;
white-space: normal;
vertical-align: middle;
}
/* flex */
.container {
display: flex;
align-items: center;
justify-content: center;
}
.container div {
width: 100px;
height: 100px;
}
/* grid */
.wrap {
background-color: rgba(102, 103, 171, 1);
width: 100px;
height: 100px;
overflow: hidden;
resize: both;
/* key code */
display: grid;
place-items: center;
}
.center {
background-color:rgba(245, 223, 77, 1);
width: 60px;
height: 20px;
border-radius: 5px
}
li 与 li 之间有看不见的空白间隔是什么原因引起的?有什么解决办法?
问题的本质是 inline-block 元素间间距换行写会占用一个字符的宽度。
不仅仅是 li 会有这个问题。
<!-- 无空白 -->
<li>测试一下</li><li>测试一下</li><li>测试一下</li>
<!-- 有空白 -->
<li>测试一下</li>
<li>测试一下</li>
<li>测试一下</li>
解决方法:
- 塞在一行写。不足:代码不美观
float: left
设置浮动。不足:有些业务场景不能使用浮动。ul
设置font-size: 0
,重新再li
设置字符大小。不足:Safari 依然会出现空白间隔- 推荐
ul
设置letter-spacing: -8px
,重新设置li
的letter-spacing: normal
清除浮动
.clear::after {
content: '';
display: block;
clear: both;
overflow: hidden;
height: 0;
}
如何修改 chrome 记住密码后自动填充表单的黄色背景?
chrome 表单自动填充后,通过审查元素可以看到 chrome 默认给表单加上了 input:-webkit-autofill 私有属性,并且写入了样式。
/* chrome 自动写入的样式 */
input:-webkit-autofill {
background-color: rgb(250, 255, 189) !important;
background-image: none !important;
color: rgb(0, 0, 0) !important;
}
/* 解决方案:使用足够大的纯色内阴影来覆盖样式 */
input:-webkit-autofill,
textarea:-webkit-autofill,
select:-webkit-autofill {
-webkit-box-shadow: 000px 1000px white inset;
border: 1px solid #CCC !important;
}
单行/多行缩略
两栏布局
三栏布局
自定义表单组件
单选、复选、输入框
多行文本展开收起
修改选中文本的样式::selection
多行文本收起展开
图片适配容器大小,等比例缩放
打字特效
图片马赛克效果
让页面里的字体变清晰,变细用 CSS 怎么做?
webkit 实现了 -webkit-font-smoothing
Firefox 实现了 -moz-osx-font-smoothing
div {
font-smooth: always;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
H5 overflow:scroll 不能平滑滚动的问题怎么处理?
结合使用两种方案
- 设置
-webkit-overflow-scrolling: touch;
,但是可能导致固定定位的元素随着页面一起滚动 - 设置
overflow
,外部设置 hidden,内容元素为 auto
div {
/* 当手指从触摸屏上移开,会保持一段时间的滚动 */
-webkit-overflow-scrolling: touch;
/* 当手指从触摸屏上移开,滚动会立即停止 */
-webkit-overflow-scrolling: auto;
}
body {
overflow-y: hidden;
}
.wrap {
overflow-y: auto;
}
H5 iOS 上拉边界下拉出现白色空白
iOS 手指按住屏幕上下拖动会触发 touchmove 事件。这个事件触发的对象是整个 webview 容器,容器被拖动,剩下的部分就会成空白。 解决方案:
- 监听事件禁止滑动
document.body.addEventListener('touchmove', function(e) {
if(e._isScroller) return;
// 阻止默认事件
e.preventDefault();
}, {
passive: false
});
- 将下拉出现白色空白做成功能,比如下拉刷新
H5 固定定位在 android 下无效怎么处理?如何限制页面缩放?
因为移动端浏览器默认的 viewport 为 layout viewport。 在移动端显示时,因为 layout viewport 的宽度大于移动端屏幕的宽度,所以页面会出现滚动条左右移动,fixed 的元素是相对layout viewport 来固定位置的,而不是移动端屏幕来固定位置的,所以会出现感觉 fixed 无效的情况。
<meta name="viewport"content="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no"/>
设置该属性还能解决一个问题:限制页面缩放。HTML 本身会产生放大或缩小的行为,通过设置就能控制缩放。
H5 click 点击事件延时与穿透
监听元素 click 事件,点击元素触发时间延迟约 300ms。
解决方案:
import FastClick from 'fastclick';
FastClick.attach(document.body, options);
H5 软键盘将页面顶起来、收起未回落问题
布局中会有个固定的底部。安卓一些版本中,输入弹窗出来,会将解压 absolute 和 fixed 定位的元素。导致可视区域变小,布局错乱。
// 记录原有的视口高度
const originalHeight = document.body.clientHeight || document.documentElement.clientHeight;
window.onresize = function(){
var resizeHeight = document.documentElement.clientHeight || document.body.clientHeight;
if(resizeHeight < originalHeight ){
// 恢复内容区域高度
// const container = document.getElementById("container")
// 例如 container.style.height = originalHeight;
}
}
const isWechat = window.navigator.userAgent.match(/MicroMessenger\/([\d\.]+)/i);
if (!isWechat) return;
const wechatVersion = wechatInfo[1];
const version = (navigator.appVersion).match(/OS (\d+)_(\d+)_?(\d+)?/);
// 如果设备类型为iOS 12+ 和 wechat 6.7.4+,恢复成原来的视口
if (+wechatVersion.replace(/\./g, '') >= 674 && +version[1] >= 12) {
window.scrollTo(0, Math.max(document.body.clientHeight, document.documentElement.clientHeight));
}
H5 页面生成为图片和二维码问题
// 二维码
import QRCode from 'qrcode';
// 使用 async 生成图片
const options = {};
const url = window.location.href;
async url => {
try {
console.log(await QRCode.toDataURL(url, options))
// TODO: 赋值给图片url
} catch (err) {
console.error(err);
}
}
// 图片
import html2canvas from 'html2canvas';
// 移动端生成出来的图片比较模糊,需要多倍生成
// 根据需要设置 scaleSize 大小
const scaleSize = 2;
const newCanvas = document.createElement("canvas");
const target = document.querySelector('div');
const width = parseInt(window.getComputedStyle(target).width);
const height = parseInt(window.getComputedStyle(target).height);
newCanvas.width = width * scaleSize;
newCanvas.height = widthh * scaleSize;
newCanvas.style.width = width + "px";
newCanvas.style.height =width + "px";
const context = newCanvas.getContext("2d");
context.scale(scaleSize, scaleSize);
html2canvas(document.querySelector('.demo'), { canvas: newCanvas }).then(function(canvas) {
// 简单的通过超链接设置下载功能
document.querySelector(".btn").setAttribute('href', canvas.toDataURL());
}
H5 调试
import Vconsole from 'vconsole'
new Vconsole()
或者通过 代理 + spy-debugger
npm install spy-debugger -g
- 手机与电脑置于同一 wifi 下,手机设置代理,设置手机的 HTTP 代理,代理 IP 地址设置为 PC 的 IP 地址,端口为spy-debugger的启动端口
spy-debugger 默认端口:9888
Android :设置 - WLAN - 长按选中网络 - 修改网络 - 高级 - 代理设置 - 手动
IOS :设置 - Wi-Fi - 选中网络, 点击感叹号, HTTP 代理手动
- 手机打开浏览器或者 app 中 H5 页面
- 打开桌面日志网站进行调试,点击控制台监听地址。查看抓包和 H5 页面结构