[css] 一些兼容性(奇怪)问题
垂直居中偏移问题
line-height
在安卓中出现往上偏移的现象。(在ios可能会出现下掉....暂不知晓原因)
原因:
- 可能是使用了奇数字号。
- 可能是字号小于12px。
本质原因:
可能是Android在排版计算的时候参考了primyfont字体的相关属性(即HHead Ascent、HHead Descent等),而primyfont的查找是看font-family
里哪个字体在fonts.xml里第一个匹配上,而原生Android下中文字体是没有family name的,导致匹配上的始终不是中文字体,所以解决这个问题就要在font-family
里显式申明中文,或者通过什么方法保证所有字符都fallback到中文字体。
解决方案:
- 针对Android 7.0+设备:
<html>
上设置lang
属性:<html lang="zh-cmn-Hans">
,同时font-family不指定英文,如font-family: sans-serif
。这个方法是利用了浏览器的字体fallback机制,让英文也使用中文字体来展示,blink早期的内核在fallback机制上存在问题,Android 7.0+才能ok,早期的内核下会导致英文fallback到Noto Sans Myanmar
,这个字体非常丑。 - 针对MIUI 8.0+设备:设置
font-family: miui
。这个方案就是显式申明中文的方案,MIUI在8.0+上内置了小米兰亭,同时在fonts.xml里给这个字体指定了family name:miui
,所以我们可以直接设置。 - 字体大小不要使用奇数字号,字号需要是能被2整除的整数且不可小于12px。
- IOS对小数的像素很敏感但Android不是,例如Android上
1.3px = 1.5px = 1.7px = 1px;
就是说小数点会被省略,但是在IOS上有很大的差异, 可以利用这个特性解决垂直居中问题,就比如说padding-top: 10.1px;
和padding-bottom: 9.9px;
Android上就变成了padding-top: 10px; padding-bottom: 9px;
- 设置
border: 1px solid transparent;
(个人经验是用padding直接撑....)
align-items
在多机型中,flex的居中出现往上偏移的现象。
目前不知道解决方案。
inline-block段落间有缝隙
在父元素中设置font-size:0
解决
disabled
input内字体的颜色,加了disabled后变化:
-webkit-text-fill-color:#880000; /* Override iOS / Android font color change */
-webkit-opacity:1; /* Override iOS opacity change affecting text & background color */
color:#880000; /* Override IE font color change */
ios
在某些?ios手机,滚动条一滑到底,会出现在fixed的dom上的click事件失效,使用-webkit-overflow-scrolling: touch
解决。
-webkit-overflow-scrolling: touch
可能会出现拉动的dom覆盖了底部fixed的footer,注意包裹内容的dom不能设置z-index
。
-webkit-overflow-scrolling: touch; 与 fixed 一起很容易出现奇怪的问题,不建议使用.
ios顶部状态栏,h5需要自己设上边距,不然会与状态栏重叠。
ios顶部状态栏的文字不一定是白色的,可能需要设置。
容器用padding-bottom撑起了底部的高度,在ios9里可能会出现滚动条异常的问题,可以改为用空容器撑起.
ios 有的transform/transition动画会闪白/抖动,网上查说是可以用这个
backface-visibility: hidden;
transform-style: preserve-3d;
perspective: 1000px;
ios错误的时钟会导致读取不到图片
安卓
部分安卓机对小数不敏感,可能四舍五入,也可能向下取整。
会导致识别不了0.5px
. rgba小数部分可能识别为0.
max-height
在安卓失效
alignItems: 'baseline'
在安卓失效
在部分安卓机上不设置line-height属性或者设置与fontSize相同的line-height可能会导致文本内容被截断,与字体关系较大
安卓和苹果的lineHeight渲染不一致(应该是因为字体的缘故)
padding
部分机型上,用padding 撑开高宽度,撑开的部分有可能触发不了绑定的事件。(下次试试加cursor:pointer
看看有没有用)
部分机型上,padding 可能撑不开高宽度。
字符串截断问题
一加,Oppo机型使用Text组件设置加粗但没有设置默认字体的情况下,存在字符串截断问题。对应issue
font-weight
pc端500 600 无效果,mobile(好点的手机)端有效果
快速连续click会触发mouseleave
不知原因,但是可以通过这种方式修复
let a = document.getElementById('a');
a.addEventListener('click', (e) => {
console.log('click trigger')
})
a.addEventListener('mouseleave', (e) => {
if (e.relatedTarget) {
console.log('mouseleave trigger')
}
})
莫名的白边
基本是因为块坍塌,使用inline-block或者产生BFC(一般用.clearfix)都可以解决
div与img间有缝隙
因为图片文字等inline元素默认是和父级元素的baseline对齐的,而baseline又和父级底边有一定距离(这个距离和 font-size,font-family 相关,不一定是 5px),所以设置 vertical-align:top/bottom/text-top/text-bottom 都可以避免这种情况出现。其他的block元素中包含img也会有这个现象。
- 给图片img标签
display:block
. - 定义父容器
font-size:0
或line-height:0
. - 定义图片img标签
vertical-align:bottom
或vertical-align:middle
或vertical-align:top
.
html空白显示为空格
换行在浏览器中会被解释为一个空格,空格和回车都会被显示为一个3px的空格。
可以在换行处父级加css {font-size:0}
; 这样换行后就不会有空格出现.
box-shadow产生额外的间距
float: left
似乎可以清除box-shadow的影响
box-sizing
父元素带有border,且设置了box-sizing:border-box,子元素width100%的话,也是取不到预想的父元素宽度的,不会取到border的宽度.
如
.father {
width: 100px;
height: 100px;
box-sizing: border-box;
border: 1px solid black;
}
.son {
width: 100%;
height: 100%;
}
son的高宽为98px . 这种情况可能把border放在son里会比较好.
一般来说line-height等于height的时候可以实现垂直居中,
但是当容器是box-sizing: border-box
时,又有padding或者border占了高度,
则需要line-height设置为真实容器高度
height: 22px;
line-height: 20px;
box-sizing: border-box;
border: 1px solid #BFE0FC;
svg
svg做background-image 似乎适配不是太好
animation
父元素的显示隐藏,会触发子元素的animation
0.5px
0.5px有时在ipx里有显示问题,特别是border,可能出现缺失一半的情况
数值比较
js里虽然支持string与number直接进行比较,但是不同位数时会出现问题,应当严格转换为number类型.
"109">"14" // false
"109">"101" // true
解构赋值默认值问题
用解构赋值写默认值的写法,如果值为null,默认赋值失效,变为null
let obj = { a: undefined, b: null, c: false, d: 0, e: '', f: NaN }
let { a = [], b = [], c = [], d = [], e = [], f = [] } = obj;
console.log(a, b, c, d, e, f)//[] null false 0 "" NaN
iconfont问题
使用iconfont图标的编码动态赋值,发现只显示编码,不显示图片
将&#x
转换成\u
,同时去除;
即可
例如:

改成:
\ue601
String(icon).replace(/^&#x(.+);$/, "\\u$1");
如果直接传\ue601
有问题,可以先进行encode