iPhone X 后时代的CSS hack

2018年12月14新增 iPhone XS、iPhone XS Max、iPhone XR 相关的内容。

以下不说明 why,只说 how。

常规方式

常规方式采用 CSS 方式,适用于包括如下但不限于如下的情形:头部或尾部有 fix 元素、需要照顾竖屏的情况

viewport 的改进

确保存在viewport-fit=cover

<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=0,viewport-fit=cover">

CSS 中的 safe-area-inset-* 变量

env()constant()是iOS11 新增特性,Webkit 的一个 CSS 函数,用于设定安全区域与边界的距离,有四个预定义的变量:

safe-area-inset-left:安全区域距离左边边界距离

safe-area-inset-right:安全区域距离右边边界距离

safe-area-inset-top:安全区域距离顶部边界距离

safe-area-inset-bottom:安全区域距离底部边界距离

使用实例

结合CSS的 @support 新特征来使用。

实例:

https://rescdn.qqmail.com/node/wework/images/201812141616.1e28af56b6.png

源代码:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>iPhone X 后时代的 CSS 兼容</title>
    <!-- viewport 的 viewport-fit=cover 不可少 -->
    <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=0,viewport-fit=cover">
    <style type="text/css">
        /* CSS Reset 实际业务中建议用 Normalize */
        * {padding: 0; margin: 0}

        /* Comment Start */
        /* 当内容不足一屏的时候,可以用这个确保也能保持100% 高度,
           当然,直接简单粗暴的`body:100vh` 也可以的
        */
        html {
            position: relative;
        }
        html,body {
            height: 100%;
        }
        /* Comment End */
        body {
            background: #272822;
            color: #FFF;
            text-align: center;
        }

        .heightDiv {
            background:#EEE;
            height:900px;
            color: #000;
        }

        .fixedDiv {
            position: fixed;
            bottom: 0;
            left: 0;
            right: 0;
            z-index: 9999;
            background-color: #555;
        }

        .fixedDiv_btn {
            margin: 10px 20px;
            background-color: #356aa0;
            color: #FFF;
            height: 30px;
            line-height: 30px;
            border-radius: 4px;
            display: block;
            text-decoration: none;
        }


        /* constant(): (iOS 11.0-11.2) */
        @supports (padding-bottom: constant(safe-area-inset-bottom)) {
          .fixedDiv_btn {
            --safe-area-inset-var: constant(safe-area-inset-bottom);
            margin-bottom: calc(10px + var(--safe-area-inset-var));
          }
        }
        /* env(): (iOS 11.2+) */
        @supports (padding-bottom: env(safe-area-inset-bottom)) {
          .fixedDiv_btn {
            --safe-area-inset-var: env(safe-area-inset-bottom);
               margin-bottom: calc(10px + var(--safe-area-inset-var));
          }
        }

        /* IPhone X 后时代的兼容,善用CSS3 的`calc()`函数 */
        .bottomDiv_inner {
            background-color: #dd4b39;
            color: #FFF;
            font-size: 20px;
            padding: 40px 0;
        }
        /* 可以用 CSS4 的变量(如前面的 fixedDiv ),也可以直接写,看实际情况*/
        @supports (padding-bottom: constant(safe-area-inset-bottom)) {
          .bottomDiv {
            padding-bottom: constant(safe-area-inset-bottom);
          }
        }
        @supports (padding-bottom: env(safe-area-inset-bottom)) {
          .bottomDiv {
            padding-bottom: env(safe-area-inset-bottom);
          }
        }

    </style>
</head>
<body>
    <p>第一行文字哈哈哈哈</p>
    <p>!!注意,body 区域是黑色的!!</p>
    <p>请右键查看源代码查看说明</p>
    <p></p>
    <p></p>
    <p></p>
    <div class="heightDiv">灰色区域撑开自然高度</div>
     <div class="fixedDiv">
         <a href="javascript:;" class="fixedDiv_btn">我是 Fixed 的元素按钮</div>
     </div>
     <div class="bottomDiv">
         <p class="bottomDiv_inner">我是自然末尾的元素</p>
     </div>
</body>
</html>

粗暴版本(不推荐,仅作备份)

通过媒体查询的方式,目前不怎么推荐这种方式了。

/*
  iPhoneX / XS 竖屏
  所有针对iPhone X竖屏情况下的hack样式都写这里面
*/
@media (device-width: 375px) and (device-height: 812px) and (-webkit-min-device-pixel-ratio: 3) and (orientation: portrait){
  body {
    height: 100vh;
  }
  .help_container {
    margin-left: constant(safe-area-inset-left);
    margin-left: env(safe-area-inset-left);
    margin-right: constant(safe-area-inset-left);
    margin-right: env(safe-area-inset-left);
  }
  .help_feedback .weui-cell{
    padding-bottom: constant(safe-area-inset-bottom);
    padding-bottom: env(safe-area-inset-bottom);
  }
}
/*
  iPhoneX / XS 横屏
*/
@media (device-width: 375px) and (device-height: 812px) and (-webkit-min-device-pixel-ratio: 3) and (orientation: landscape){}

/*
  iPhoneXR
*/
/* 1792x828px at 326ppi */
@media only screen
    and (device-width : 414px)
    and (device-height : 896px)
    and (-webkit-device-pixel-ratio : 2) { }

/*
  iPhone XS Max
*/
/* 2688x1242px at 458ppi */
@media only screen
    and (device-width : 414px)
    and (device-height : 896px)
    and (-webkit-device-pixel-ratio : 3) { }

其它说明

  • iPhone X 后时代的CSS 兼容,善用CSS3 的calc()函数。

  • 当你的页面自然高度不满屏的时候,有些第三方客户端的 webview 会自作聪明地帮你加个底部的 safe area margin bottom。有洁癖的设计师可能会要求你去掉,如果要去掉,有如下两种方式:

    (1)直接一句body {height:100vh;} 撑大高度,简单粗暴。

    (2)传统的撑高高度的样式。

      html {
              position: relative;
          }
          html,body {
              height: 100%;
          }
    

附录

Apple 官方文档:https://developer.apple.com/ios/human-interface-guidelines/overview/iphone-x/

英文资料:https://webkit.org/blog/7929/designing-websites-for-iphone-x/ , https://medium.com/@draganeror/iphone-x-layout-features-with-css-environment-variables-d57423433dec

外部页面介绍:https://aotu.io/notes/2017/11/27/iphonex/index.html (注意该文最后一段 @support 的说法有问题,不一定只有iPhone 支持)

© DeveWork.com 2018. sitemap  统计 Updated at 2020-02-24 10:54

results matching ""

    No results matching ""