移动端:横屏适配、图片模糊、1px问题

目录

一、横屏适配

1、JavaScript检测横屏

2、CSS检测横屏

二、图片模糊问题

1、产生原因

2、解决方案

3、media查询

4、image-set

5、srcset

6、JavaScript 拼接图片url

7、使用svg

三、1px问题

1、border-image

2、background-image

3、伪类 + transform

4、svg


一、横屏适配

很多视口我们要对横屏和竖屏显示不同的布局,所以我们需要检测在不同的场景下给定不同的样式:

1、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('横屏');
    }
});

2、CSS检测横屏

@media screen and (orientation: portrait) {
    /*竖屏...*/
}

@media screen and (orientation: landscape) {
    /*横屏...*/
}

二、图片模糊问题

1、产生原因

我们平时使用的图片大多数都属于位图( png、jpg...),位图由一个个像素点构成的,每个像素都具有特定的位置和颜色值:

理论上,位图的每个像素对应在屏幕上使用一个物理像素来渲染,才能达到最佳的显示效果。

而在 dpr>1的屏幕上,位图的一个像素可能由多个物理像素来渲染,然而这些物理像素点并不能被准确的分配上对应位图像素的颜色,只能取近似值,所以相同的图片在 dpr>1的屏幕上就会模糊:

2、解决方案

为了保证图片质量,我们应该尽可能让一个屏幕像素来渲染一个图片像素,所以,针对不同 DPR的屏幕,我们需要展示不同分辨率的图片。

如:在 dpr=2的屏幕上展示两倍图 (@2x),在 dpr=3的屏幕上展示三倍图 (@3x)

3、media查询

使用 media查询判断不同的设备像素比来显示不同精度的图片

.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);
    }
}

只适用于背景图

4、image-set

使用 image-set

.avatar {
    background-image: -webkit-image-set( "conardLi_1x.png" 1x, "conardLi_2x.png" 2x );
}

只适用于背景图

5、srcset

使用 img标签的 srcset属性,浏览器会自动根据像素密度匹配最佳显示图片:

<img src="conardLi_1x.png"
srcset=" conardLi_2x.png 2x, conardLi_3x.png 3x">

6、JavaScript 拼接图片url

使用 window.devicePixelRatio获取设备像素比,遍历所有图片,替换图片地址:

const dpr = window.devicePixelRatio;
const images = document.querySelectorAll('img');
images.forEach((img)=>{
    img.src.replace(".", `@${dpr}x.`);
})

7、使用svg

SVG的全称是可缩放矢量图( ScalableVectorGraphics。不同于位图的基于像素, SVG 则是属于对图像的形状描述,所以它本质上是文本文件,体积较小,且不管放大多少倍都不会失真

除了我们手动在代码中绘制 svg,我们还可以像使用位图一样使用 svg图片:

<img src="conardLi.svg">

<img src="data:image/svg+xml;base64,[data]">
.avatar {
    background: url(conardLi.svg);
}

三、1px问题

为了适配各种屏幕,我们写代码时一般使用设备独立像素来对页面进行布局。而在设备像素比大于 1的屏幕上,我们写的 1px实际上是被多个物理像素渲染,这就会出1px在有些屏幕上看起来很粗的现象

1、border-image

基于 media查询判断不同的设备像素比给定不同的 border-image

.border_1px {
    border-bottom: 1px solid #000;
}

@media only screen and (-webkit-min-device-pixel-ratio:2) {
    .border_1px {
        border-bottom: none;    
        border-width: 0 0 1px 0;
        border-image: url(../img/1pxline.png) 0 0 2 0 stretch;
    }
}

2、background-image

border-image类似,准备一张符合条件的边框背景图,模拟在背景上。

.border_1px {
    border-bottom: 1px solid #000;
}

@media only screen and (-webkit-min-device-pixel-ratio:2) {
    .border_1px {
        background: url(../img/1pxline.png) repeat-x left bottom;
        background-size: 100% 1px;
    }
}

上面两种都需要单独准备图片,而且圆角不是很好处理,但是可以应对大部分场景。

3、伪类 + transform

media查询判断不同的设备像素比对线条进行缩放:

.border_1px:before {
    content: '';
    position: absolute;
    top: 0;
    height: 1px;
    width: 100%;
    background-color: #000;
    transform-origin: 50% 0%;
}


@media only screen and (-webkit-min-device-pixel-ratio:2) {
    .border_1px:before {    
        transform: scaleY(0.5);
    }
}


@media only screen and (-webkit-min-device-pixel-ratio:3) {
    .border_1px:before {
        transform: scaleY(0.33);
    }
}

这种方式可以满足各种场景,如果需要满足圆角,只需要给伪类也加上 border-radius即可。

4、svg

上面我们 border-imagebackground-image都可以模拟 1px边框,但是使用的都是位图,还需要外部引入。

借助 PostCSSpostcss-write-svg我们能直接使用 border-imagebackground-image创建 svg1px边框:

@svg border_1px {
    height: 2px;
    @rect {
        fill: var(--color, black);
        width: 100%;
        height: 50%;
    }
}

.example { 
    border: 1px solid transparent; 
    border-image: svg(border_1px param(--color #00b1ff)) 2 2 stretch; 
}

上面的方案是大漠在他的文章中推荐使用的,基本可以满足所有场景,而且不需要外部引入,这是我个人比较喜欢的一种方案。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值