css的手机适配
在html篇里提到设置视口宽度和设备宽度,固定的meta配置就是写死的,死记硬背
应该清楚的是手机端的适配应该克服的难题就是宽度根据手机屏幕的大小变化,而高度却没有办法跟随比例变化,也就是宽高比
,比如在手机上要一行上排列三个div放正方形的三个div,要怎么做,三个div浮动排列后各自设置width为33.3%,那高度呢,在pc端可以直接100*100,但是手机不行,不等比排列太难看了,并且pc的字体就是固定的16px或者14px,但是手机有大小的区别,也应该根据手机变化,这就是手机适配要解决的
两个方案
- 一个是rem
- 一个vw,vh的css3的api
在css里有px和em还有rem
- px就是固定的,是指一个视口像素,而不是设备像素,很高深,不用深究,px是个固定的计量单位
- em是相对父元素的字体大小的大小,比如父元素的字体大小是16px,那1em就是16px,他不是个固定值,是个相对值,非常不常用,用处就是在一些文章的段落前用2em作为两个字的缩进
- 而rem也是个相对值,但相对的不是父元素的字体大小,而是html标签的字体大小,而html就是跟手机宽度相等的存在,也就是说只要把html的字体大小设置为375px,那1rem就是375px,再把div高度设置成0.33rem,这样就可以实现永远正方形的div,这就是传说中的rem适配
rem的关键点就是如何去给html标签设置跟设配宽度一样的字体大小,而现实是只能用js
去实现,而且为了更好的计算,不能计算为1rem去等于设备宽度,这样如果要10px就是零点零几的rem,正确的做法是让html等于10rem,15rem,20rem,我一般是用15rem,就是375/15=25,也就是1rem=25px,16px的正常字体大小就是16/25约等于0.65rem,rem的单位是可以代替所有的px的存在的,比如padding,margin,border,img-width等等都是可以用rem的,这样不管在怎么样大小的手机上大小,任何一个元素的宽高比都是一样的,也就是等比缩放
// 如果看不懂js写了什么,也不用管,固定写法,写进去就可以用了
window.onload = function(){
/* 第一个参数是你想让 1rem 等于多少像素,第二个参数是设计稿的宽度 */
getRem(50,750)
};
window.onresize = function(){
getRem(50,750)
};
function getRem(prem,pwidth){
var oWidth = document.body.clientWidth || document.documentElement.clientWidth;
document.documentElement.style.fontSize = prem/pwidth*oWidth + "px";
}
#aa{
width:5rem;
font-size:0.6vw;
...
}
上面讲了css的3个计量单位,而css3出现了一个新的计量单位vw , vh
,这两个是相对于手机设备宽度的固定值,相对的固定值怎么理解呢,就是不管在任何设备,100vw就是等屏幕一样宽,100vh就是跟屏幕一样高,所以宽高都是33.3vw的div就是一个永远固定的正方形
#aa{
width:33.3vw;
font-size:5vw;
...
}
还可以把vw和rem合起来使用,就不用写js的rem了
html {
font-size: calc(100vw / 3.75);
}
body {
font-size: 0.14rem;
}
2020/03/04补充
今天甲方说有个人的手机用画布生成的海报里的手机号码超出了画布,但是这个手机号码的文字大小不是固定的,是计算的,不应该会出现超出画布的可能行,打印出来的计算结果也跟我一样是40px,突然意识到这是手机被设置了文字倍数,因为有些人近视什么的,于是就研究了下怎么解决这个问题
<script type="text/javascript">
var rem = 50 / 750 * document.documentElement.clientWidth;
document.documentElement.style.fontSize = rem + 'px';
</script>
<body style="font-size: 0.6rem;margin: 0;">
<span style="font-size: 16px;" id="a">我</span>
<span style="font-size: 1rem;" id="b">我</span>
<span style="font-size: 10vw;" id="c">我</span>
<div style="width: 16px;" id="d"></div>
<div style="width: 1rem;" id="e"></div>
<div style="width: 10vw;" id="f"></div>
</body>
在手机浏览器打开上面的网页,打印出当前window的宽度和几个dom元素的宽度,然后再放大或者缩小系统字体,结果的到这个答案
- window的宽度不会改变
- font-size属性都会改变
- width属性用rem的会改变
如何让修改了系统的用户也
- 宽高都用px或vw-vh去做
- 对比上面的#a和#d的宽度,计算出放大或者缩小的比例,然后把原本的字体大小适配方案改成百分比,如下,然后给body添加字体大小,大概是
0.6/(2-比例)
// 旧
<span>我</span>
<span style="font-size: 0.6rem">我</span>
<span style="font-size: 0.7rem">我</span>
<span style="font-size: 0.8rem">我</span>
// 新
<span>我</span>
<span style="font-size: 100%">我</span>
<span style="font-size: 120%">我</span>
<span style="font-size: 140%">我</span>
适配问题还有,查看文章
- 1px问题
- iphoneX适配
- 横屏适配
// JavaScript检测横屏
window.orientation:获取屏幕旋转方向
window.addEventListener("resize", ()=>{
if (window.orientation === 180 || window.orientation === 0) {
// 正常方向或屏幕旋转180度
console.log('竖屏');
};
if (window.orientation === 90 || window.orientation === -90 ){
// 屏幕顺时钟旋转90度或屏幕逆时针旋转90度
console.log('横屏');
}
});
// CSS检测横屏
@media screen and (orientation: portrait) {
/*竖屏...*/
}
@media screen and (orientation: landscape) {
/*横屏...*/
}
- 图片模糊问题
.avatar{
background-image: url(conardLi_1x.png);
}
@media only screen and (-webkit-min-device-pixel-ratio:2){
.avatar{
background-image: url(conardLi_2x.png);
}
}
@media only screen and (-webkit-min-device-pixel-ratio:3){
.avatar{
background-image: url(conardLi_3x.png);
}
}