添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

em: 相对长度单位,相对于父级元素的字体大小或浏览器的默认字体尺寸, 注意: 元素的 width/height/padding/margin em 的话相对于该元素自身的font-size。

rem: 相对长度单位,相对于页面 根元素html 的字体大小。

rpx: 是微信小程序解决自适应屏幕尺寸的尺寸单位。微信小程序规定以 iPhone6 标准,屏幕宽度为 375px ,把它分为 750rpx 1rpx = 0.5px 。微信小程序同时也支持 rem 尺寸单位, 规定屏幕的宽度为 20rem , 所以 1rem = (750/20)rpx = 37.5 rpx

.box {
    font-size: 4em; /* 4 x 16 = 64 相对于浏览器默认font-size大小16px的倍数 */
    width: 5em; /* 5 * 4 x 16 = 320  其他属性的大小为相对于元素自身font-size大小的倍数 */
    height: 5em; /* 5 * 4 x 16 = 320  其他属性的大小为相对于元素自身font-size大小的倍数 */
    border: 2px solid gold;
.child {
    font-size: 0.5em; /* 0.5 x 64 = 32 相对于父元素font-size大小的倍数 */
    width: 5em; /* 5 x 0.5 x 16 = 160  其他属性的大小为相对于元素自身font-size大小的倍数 */
    height: 5em; /* 5 x 0.5 x 16 = 160  其他属性的大小为相对于元素自身font-size大小的倍数 */
    background-color: antiquewhite;
<div class="box">
    我是父元素
    <div class="child">我是子元素</div>
</div>

二、屏幕尺寸、分辨率、PPI(像素密度)的关系

屏幕尺寸: 显示器对角线的物理长度,1英寸=2.54厘米。
物理分辨率:,屏幕横向和纵向分布的像素点数,逻辑分辨率以point(pt)为单位,物理分辨率以pixel(px)为单位。如1920 x 1080【在使用显示器时选择过低分辨率,会让原本正常显示的内容有很大的缩放比,容易出现看不全所有内容的情况,这时需要调整系统的缩放比例才能正常使用;在使用小尺寸显示器时选择过高分辨率,会让原本正常显示的内容有很大的缩放比。容易出现缩小而看不清文字的情况】
PPI: (Pixels Per Inch),含义是显示器屏幕每英寸所拥有的像素数量,PPI是计算的显示器对角线上每英寸直线穿过的像素数【相同显示面积下的PPI越高,对机器性能的要求就越大。游戏在4K分辨率下要比2K分辨率下的帧数低很多。一般玩家会选择降低分辨率以获得流畅的游戏体验】
清晰度: PPI决定图像清晰度高低;而分辨率仅代表像素数量,但屏幕大小未考虑进去。

区分逻辑分辨率和物理分辨率,是因为在早期iPhone 3GS之前,iOS绘制图形以point为单位。在这个时期point和pixel严格对应在一起。在iPhone 3GS上:1 pt = 1 px。到了iPhone 4开始,苹果引入了Retina屏幕。在一定物理单位内可以显示2倍的像素。iPhone 4的屏幕物理尺寸还是3.5寸,分辨率为640 × 960,提升了4倍。也就是说,原先的1 point可以容纳4个pixel。

历代iPhone的分辨率

CSS像素 或 逻辑像素 或 设备独立像素: 操作系统定义的单位。如果手机分辨率翻倍,图像不就要被缩小一倍,难道要针对每个设备都出个设计稿?每个设备的分辨不尽相同,其实这个问题乔帮主在很多年前就想到了——就是逻辑分辨率;在iPhone4使用的视网膜屏幕中,把2x2个物理像素当1个像素使用,这样让屏幕看起来更精致,但是元素的大小却不会改变。从此以后高分辨率的设备,多了一个逻辑像素。既然逻辑像素由物理像素得来,那他们就会有一个像素比值,像素比会产生一个非常经典的问题,1像素边框的问题。

设备像素 或 物理像素: 设备能够控制显示的最小单位

  • 设备像素比: 设备像素比 = 设备像素 / 设备独立像素,单位是dpr(device pixel radio);PPI值越高,意味着有更细腻的画面;而在一定的距离内,手机显示屏在200PPI以上时,肉眼就分辨不出单个像素点了,所以没必要过度追求超高的PPI。
  • 1px边框问题 (物理像素 => 逻辑像素)进行显示

    css里写的1px的时候,由于它是逻辑像素,导致逻辑像素根据这个设备像素比(dpr)去映射到设备上就为2px,或者3px,由于每个设备的屏幕尺寸不一样,就导致每个物理像素渲染出来的大小也不同(记得上面的知识点吗,设备的像素大小是不固定的),这样如果在尺寸比较大的设备上,1px渲染出来的样子相当的粗矿,这就是经典的一像素边框问题

    transform: scale(0.5) 方案

    @media only screen and (-webkit-min-device-pixel-ratio: 2.0) {
        .border-bottom::after {
            display: block;
            content: '';
            height: 1px;
            background:#000;
            transform: scaleY(0.5);
    

    四. 屏幕适配解决方案

    视口(viewport)代表当前可见的计算机图形区域。在Web浏览器术语中,通常与浏览器窗口相同,但不包括浏览器的UI, 菜单栏等——即指你正在浏览的文档的那一部分。其中user-scalable设置为 no 可以解决移动端点击事件延迟问题(拓展)

    <meta name="viewport" content="width=device-width; initial-scale=1; maximum-scale=1; minimum-scale=1; user-scalable=no;">
    

    UI给我们的原型图一般是基于iphone6设备机型的像素给定的;为了适配所有机型,我们在写样式时需要把物理像素转换为设备独立像素

    方法一:基于 rem 的 flexible方案(已经被官方弃用)

    由于viewport单位得到众多浏览器的兼容,lib-flexible这个过渡方案已经可以放弃使用,不管是现在的版本还是以前的版本,都存有一定的问题。建议大家开始使用viewport来替代此方案。(来自lib-flexible团队)

    它的核心代码非常简单:

    // set 1rem = viewWidth / 10
    function setRemUnit () {
        const rem = document.documentElement.clientWidth.clientWidth / 10
        docEl.style.fontSize = rem + 'px'
    // reset rem unit on page resize
    window.addEventListener('resize', setRemUnit)
    window.addEventListener('pageshow', function (e) {
        if (e.persisted) {
          setRemUnit()
    

    上面的代码中,将html节点的font-size设置为页面clientWidth(布局视口)的1/10,即1rem就等于页面布局视口的1/10,这就意味着我们后面使用的rem都是按照页面比例来计算的。

    iPhone6为例:布局视口为375px,则1rem = 37.5px,这时UI给定一个元素的宽为75px(设备独立像素),我们只需要将它设置为75 / 37.5 = 2rem

    当然,每个布局都要计算非常繁琐,我们可以借助PostCSSpx2rem插件来帮助我们完成这个过程。

    被弃用原因: 没有考虑到设备像素比,用户使用更大的屏幕,是想看到更多的内容,而不是更大的字;仅仅只是随屏幕大小同步放大或缩小页面内容

    方法二:vh、vw方案

    vh、vw方案即将视觉视口宽度 window.innerWidth和视觉视口度 window.innerHeight 等分为 100 份。

  • vw(Viewport's width)1vw等于视觉视口的1%
  • vh(Viewport's height) :1vh 为视觉视口高度的1%
  • vmin : vw 和 vh 中的较小值
  • vmax : 选取 vw 和 vh 中的较大值
  • 如果视觉视口为375px,那么1vw = 3.75px,这时UI给定一个元素的宽为75px(设备独立像素),我们只需要将它设置为75 / 3.75 = 20vw

    这里的比例关系我们也不用自己换算,我们可以使用PostCSS的 postcss-px-to-viewport 插件帮我们完成这个过程。写代码时,我们只需要根据UI给的设计图写px单位即可。

    vw同样有一定的缺陷:

  • px转换成vw不一定能完全整除,因此有一定的像素差。
  • 比如当容器使用vwmargin采用px时,很容易造成整体宽度超过100vw,从而影响布局效果。当然我们也是可以避免的,例如使用padding代替margin,结合calc()函数使用等等...
  • 方法三:viewport + window.devicePixelRatio + rem

    实现原理: 首先通过JS动态获取window.devicePixelRatio,然后动态修改具有viewport属性的meta标签元素的content属性 (个人觉得最好、个人最推荐的方法)

    blog.csdn.net/qq131125669…

    www.meow7.cn/index.php/a…

    方法四:Flex布局

    方法五:媒体查询

    @media only screen
      and (min-width: 320px)
      and (max-width: 480px)
      and (resolution: 150dpi) { /* 表示输出设备的像素密度,即其分辨率 */
        body { line-height: 1.4; }
    @media (-webkit-device-pixel-ratio: 1) { /* 设备像素比 */
      p { color: red; }
    /* Minimum resolution */
    @media (-webkit-min-device-pixel-ratio: 1.1) {
      p { font-size: 1.5em;}
    /* Maximum resolution */
    @media (-webkit-max-device-pixel-ratio: 3) {
      p { background: yellow;}
    /* 媒体查询第4级引入了一种新的范围语 */
    @media (height > 600px) {
        body { line-height: 1.4; }
    @media (400px <= width <= 700px) {
        body { line-height: 1.4; }
    

    七、适配iPhoneX

    iPhoneX的出现将手机的颜值带上了一个新的高度,它取消了物理按键,改成了底部的小黑条,但是这样的改动给开发者适配移动端又增加了难度。

    7.1 安全区域

    iPhoneX发布后,许多厂商相继推出了具有边缘屏幕的手机。

    这些手机和普通手机在外观上无外乎做了三个改动:圆角(corners)、刘海(sensor housing)和小黑条(Home Indicator)。为了适配这些手机,安全区域这个概念变诞生了:安全区域就是一个不受上面三个效果的可视窗口范围。

    为了保证页面的显示效果,我们必须把页面限制在安全范围内,但是不影响整体效果。

    7.2 viewport-fit

    viewport-fit是专门为了适配iPhoneX而诞生的一个属性,它用于限制网页如何在安全区域内进行展示。

    contain: 可视窗口完全包含网页内容

    cover:网页内容完全覆盖可视窗口

    默认情况下或者设置为autocontain效果相同。

    7.3 env、constant

    我们需要将顶部和底部合理的摆放在安全区域内,iOS11新增了两个CSS函数env、constant,用于设定安全区域与边界的距离。

    函数内部可以是四个常量:

  • safe-area-inset-left:安全区域距离左边边界距离
  • safe-area-inset-right:安全区域距离右边边界距离
  • safe-area-inset-top:安全区域距离顶部边界距离
  • safe-area-inset-bottom:安全区域距离底部边界距离
  • 注意:我们必须指定viweport-fit后才能使用这两个函数:

    <meta name="viewport" content="viewport-fit=cover">
    

    constantiOS < 11.2的版本中生效,enviOS >= 11.2的版本中生效,这意味着我们往往要同时设置他们,将页面限制在安全区域内:

    body {
      padding-bottom: constant(safe-area-inset-bottom);
      padding-bottom: env(safe-area-inset-bottom);
    

    当使用底部固定导航栏时,我们要为他们设置padding值:

    padding-bottom: constant(safe-area-inset-bottom); padding-bottom: env(safe-area-inset-bottom);

    八、横屏适配

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

    8.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('横屏');
    

    8.2 CSS检测横屏

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

    九、图片模糊问题

    9.1 产生原因

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

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

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

    9.2 解决方案

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

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

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

    只适用于背景图\

    9.4 image-set

    使用image-set

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

    只适用于背景图\

    9.5 srcset

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

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

    9.6 JavaScript拼接图片url

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

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

    9.7 使用svg

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

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

    <img src="conardLi.svg">
    <img src="data:image/svg+xml;base64,[data]">
    .avatar {
      background: url(conardLi.svg);
    
  • 99designs.com/blog/tips/p…
  • www.w3cplus.com/css/vw-for-…
  • aotu.io/notes/2017/…
  • 用户5478764823586
    粉丝