20 lines
42 KiB
HTML
20 lines
42 KiB
HTML
<!doctype html>
|
||
<html lang="en" dir="ltr">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||
<meta name="generator" content="Docusaurus v2.0.0-beta.5">
|
||
<link rel="search" type="application/opensearchdescription+xml" title="HZFE - 剑指前端 Offer" href="/awesome-interview/opensearch.xml">
|
||
<link rel="preconnect" href="https://hm.baidu.com">
|
||
<script>var _hmt=_hmt||[];!function(){var e=document.createElement("script");e.src="https://hm.baidu.com/hm.js?c7cd0fd77ac518cc6ef46461cdc9524b";var c=document.getElementsByTagName("script")[0];c.parentNode.insertBefore(e,c)}()</script><title data-react-helmet="true">移动端自适应的常见手段 | HZFE - 剑指前端 Offer</title><meta data-react-helmet="true" name="twitter:card" content="summary_large_image"><meta data-react-helmet="true" property="og:url" content="https://febook.hzfe.org/awesome-interview/book3/css-mobile-adaptive"><meta data-react-helmet="true" name="docsearch:language" content="en"><meta data-react-helmet="true" name="docsearch:version" content="current"><meta data-react-helmet="true" name="docsearch:docusaurus_tag" content="docs-default-current"><meta data-react-helmet="true" property="og:title" content="移动端自适应的常见手段 | HZFE - 剑指前端 Offer"><meta data-react-helmet="true" name="description" content="相关问题"><meta data-react-helmet="true" property="og:description" content="相关问题"><link data-react-helmet="true" rel="shortcut icon" href="/awesome-interview/img/favicon.ico"><link data-react-helmet="true" rel="canonical" href="https://febook.hzfe.org/awesome-interview/book3/css-mobile-adaptive"><link data-react-helmet="true" rel="alternate" href="https://febook.hzfe.org/awesome-interview/book3/css-mobile-adaptive" hreflang="en"><link data-react-helmet="true" rel="alternate" href="https://febook.hzfe.org/awesome-interview/book3/css-mobile-adaptive" hreflang="x-default"><link data-react-helmet="true" rel="preconnect" href="https://BH4D9OD16A-dsn.algolia.net" crossorigin="anonymous"><link rel="stylesheet" href="/awesome-interview/assets/css/styles.304d13b7.css">
|
||
<link rel="preload" href="/awesome-interview/assets/js/runtime~main.e4536af0.js" as="script">
|
||
<link rel="preload" href="/awesome-interview/assets/js/main.52f9823f.js" as="script">
|
||
</head>
|
||
<body>
|
||
<script>!function(){function t(t){document.documentElement.setAttribute("data-theme",t)}var e=function(){var t=null;try{t=localStorage.getItem("theme")}catch(t){}return t}();t(null!==e?e:"light")}()</script><div id="__docusaurus">
|
||
<div><a href="#" class="skipToContent_1oUP">Skip to main content</a></div><nav class="navbar navbar--fixed-top navbarHideable_2qcr"><div class="navbar__inner"><div class="navbar__items"><button aria-label="Navigation bar toggle" class="navbar__toggle clean-btn" type="button" tabindex="0"><svg width="30" height="30" viewBox="0 0 30 30" aria-hidden="true"><path stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2" d="M4 7h22M4 15h22M4 23h22"></path></svg></button><a class="navbar__brand" href="/awesome-interview/"><img src="/awesome-interview/img/badge.svg" alt="HZFE" class="themedImage_1VuW themedImage--light_3UqQ navbar__logo"><img src="/awesome-interview/img/badge.svg" alt="HZFE" class="themedImage_1VuW themedImage--dark_hz6m navbar__logo"><b class="navbar__title">剑指前端 Offer</b></a></div><div class="navbar__items navbar__items--right"><a href="https://github.com/hzfe/awesome-interview" target="_blank" rel="noopener noreferrer" class="navbar__item navbar__link"><span>GitHub<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_3J9K"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></span></a><div class="searchBox_1Doo"><button type="button" class="DocSearch DocSearch-Button" aria-label="Search"><span class="DocSearch-Button-Container"><svg width="20" height="20" class="DocSearch-Search-Icon" viewBox="0 0 20 20"><path d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z" stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"></path></svg><span class="DocSearch-Button-Placeholder">Search</span></span><span class="DocSearch-Button-Keys"></span></button></div></div></div><div role="presentation" class="navbar-sidebar__backdrop"></div></nav><div class="main-wrapper docs-wrapper docs-doc-page"><div class="docPage_31aa"><button class="clean-btn backToTopButton_35hR" type="button"><svg viewBox="0 0 24 24" width="28"><path d="M7.41 15.41L12 10.83l4.59 4.58L18 14l-6-6-6 6z" fill="currentColor"></path></svg></button><aside class="docSidebarContainer_3Kbt"><div class="sidebar_15mo sidebarWithHideableNavbar_267A"><a tabindex="-1" class="sidebarLogo_3h0W" href="/awesome-interview/"><img src="/awesome-interview/img/badge.svg" alt="HZFE" class="themedImage_1VuW themedImage--light_3UqQ"><img src="/awesome-interview/img/badge.svg" alt="HZFE" class="themedImage_1VuW themedImage--dark_hz6m"><b>剑指前端 Offer</b></a><nav class="menu thin-scrollbar menu_Bmed menuWithAnnouncementBar_2WvA"><ul class="menu__list"><li class="menu__list-item"><a class="menu__link" href="/awesome-interview/about">关于我们</a></li><li class="menu__list-item"><a class="menu__link" href="/awesome-interview/">前言</a></li><li class="menu__list-item menu__list-item--collapsed"><a class="menu__link menu__link--sublist" href="#">模拟题一</a></li><li class="menu__list-item menu__list-item--collapsed"><a class="menu__link menu__link--sublist" href="#">模拟题二</a></li><li class="menu__list-item"><a class="menu__link menu__link--sublist menu__link--active" href="#">模拟题三</a><ul style="display:block;overflow:visible;height:auto" class="menu__list"><li class="menu__list-item"><a class="menu__link" tabindex="0" href="/awesome-interview/book3/browser-event-loop">浏览器:浏览器事件循环</a></li><li class="menu__list-item"><a class="menu__link" tabindex="0" href="/awesome-interview/book3/browser-memory-leaks">浏览器:如何定位内存泄露</a></li><li class="menu__list-item"><a class="menu__link" tabindex="0" href="/awesome-interview/book3/engineer-webpack-loader">工程化:谈下 webpack loader 的机制</a></li><li class="menu__list-item"><a class="menu__link" tabindex="0" href="/awesome-interview/book3/frame-react-hooks">框架:React Hooks 实现原理</a></li><li class="menu__list-item"><a class="menu__link" tabindex="0" href="/awesome-interview/book3/frame-diff">框架:常见框架的 Diff 算法</a></li><li class="menu__list-item"><a class="menu__link" tabindex="0" href="/awesome-interview/book3/js-async">基础:JavaScript 异步编程</a></li><li class="menu__list-item"><a class="menu__link" tabindex="0" href="/awesome-interview/book3/js-ts-interface-type">基础:TypeScript 中的 Interface 和 Type Alias</a></li><li class="menu__list-item"><a class="menu__link menu__link--active" aria-current="page" tabindex="0" href="/awesome-interview/book3/css-mobile-adaptive">样式:移动端自适应的常见手段</a></li><li class="menu__list-item"><a class="menu__link" tabindex="0" href="/awesome-interview/book3/network-http-1-2">网络:HTTP2 和 HTTP1.1 的对比</a></li><li class="menu__list-item"><a class="menu__link" tabindex="0" href="/awesome-interview/book3/coding-arr-to-tree">编码:将列表还原为树状结构</a></li><li class="menu__list-item"><a class="menu__link" tabindex="0" href="/awesome-interview/book3/algorithm-binary-tree-k">算法:二叉搜索树的第 k 个结点</a></li><li class="menu__list-item"><a class="menu__link" tabindex="0" href="/awesome-interview/book3/topic-white-screen-optimization">综合:如何减少白屏的时间</a></li></ul></li></ul></nav><button type="button" title="Collapse sidebar" aria-label="Collapse sidebar" class="button button--secondary button--outline collapseSidebarButton_1CGd"><svg width="20" height="20" aria-hidden="true" class="collapseSidebarButtonIcon_3E-R"><g fill="#7a7a7a"><path d="M9.992 10.023c0 .2-.062.399-.172.547l-4.996 7.492a.982.982 0 01-.828.454H1c-.55 0-1-.453-1-1 0-.2.059-.403.168-.551l4.629-6.942L.168 3.078A.939.939 0 010 2.528c0-.548.45-.997 1-.997h2.996c.352 0 .649.18.828.45L9.82 9.472c.11.148.172.347.172.55zm0 0"></path><path d="M19.98 10.023c0 .2-.058.399-.168.547l-4.996 7.492a.987.987 0 01-.828.454h-3c-.547 0-.996-.453-.996-1 0-.2.059-.403.168-.551l4.625-6.942-4.625-6.945a.939.939 0 01-.168-.55 1 1 0 01.996-.997h3c.348 0 .649.18.828.45l4.996 7.492c.11.148.168.347.168.55zm0 0"></path></g></svg></button></div></aside><main class="docMainContainer_3ufF"><div class="container padding-top--md padding-bottom--lg"><div class="row"><div class="col docItemCol_3FnS"><div class="docItemContainer_33ec"><article><div class="tocCollapsible_1PrD tocMobile_3Hoh"><button type="button" class="clean-btn tocCollapsibleButton_2O1e">On this page</button></div><div class="markdown"><header><h1>移动端自适应的常见手段</h1></header><h2><a aria-hidden="true" tabindex="-1" class="anchor anchor__h2 anchorWithHideOnScrollNavbar_3R7-" id="相关问题"></a>相关问题<a class="hash-link" href="#相关问题" title="Direct link to heading">#</a></h2><ul><li>介绍 meta 的 viewport 值</li><li>rem 和 vw 的值是根据什么计算的</li><li>1px 显示问题</li><li>如何适配刘海屏</li></ul><h2><a aria-hidden="true" tabindex="-1" class="anchor anchor__h2 anchorWithHideOnScrollNavbar_3R7-" id="回答关键点"></a>回答关键点<a class="hash-link" href="#回答关键点" title="Direct link to heading">#</a></h2><p><code>viewport</code> <code>相对单位</code> <code>媒体查询</code> <code>响应式图片</code></p><p>移动端开发的主要痛点是如何让页面适配各种不同的终端设备,使不同的终端设备都拥有基本一致的视觉效果和交互体验。移动端常见的适配方案有以下几种,一般都是互相搭配使用。包括:</p><ul><li>视口元信息配置</li><li>响应式布局</li><li>相对单位</li><li>媒体查询</li><li>响应式图片</li><li>安全区域适配</li></ul><h2><a aria-hidden="true" tabindex="-1" class="anchor anchor__h2 anchorWithHideOnScrollNavbar_3R7-" id="知识点深入"></a>知识点深入<a class="hash-link" href="#知识点深入" title="Direct link to heading">#</a></h2><h3><a aria-hidden="true" tabindex="-1" class="anchor anchor__h3 anchorWithHideOnScrollNavbar_3R7-" id="1-相关概念"></a>1. 相关概念<a class="hash-link" href="#1-相关概念" title="Direct link to heading">#</a></h3><h4><a aria-hidden="true" tabindex="-1" class="anchor anchor__h4 anchorWithHideOnScrollNavbar_3R7-" id="11-像素"></a>1.1 像素<a class="hash-link" href="#11-像素" title="Direct link to heading">#</a></h4><p><img src="https://user-images.githubusercontent.com/17002181/129163975-62428afd-e028-4f7f-a676-10781905e37e.png" alt="image"></p><p><strong>分辨率(Resolution)</strong></p><p>分辨率是指位图图像中细节的精细程度,以每英寸像素(ppi)衡量。每英寸的像素越多,分辨率就越高。</p><p><strong>物理像素(Physical pixels)</strong></p><p>物理像素是一个设备的实际像素数。</p><p><strong>逻辑像素(Logical pixels)</strong></p><p>是一种抽象概念。在不同的设备下,一个逻辑像素代表的物理像素数不同。CSS 像素是逻辑像素。</p><p>为了在不同尺寸和密度比的设备上表现出一致的视觉效果,使用逻辑像素描述一个相同尺寸的物理单位。在具有高密度比的屏幕下,一个逻辑像素对应多个物理像素。</p><p><strong>设备像素比(Device Pixel Ratio)</strong></p><p>当前显示设备的物理像素分辨率与 CSS 像素分辨率之比。</p><p><strong>相关问题:图片或 1px 边框显示模糊</strong></p><p>在移动端中,常见图片或者 1px 的边框在一些机型下显示模糊/变粗的问题。基于对像素相关的概念理解,可知 CSS 中的 1px 是指一个单位的逻辑像素。一个单位的逻辑像素映射到不同像素密度比的设备下,实际对应的物理像素不同。</p><p>因此,同样尺寸的图片在高密度比的设备下,由于一个位图像素需要应用到多个物理像素上,所以会比低密度比设备中的视觉效果模糊。</p><h4><a aria-hidden="true" tabindex="-1" class="anchor anchor__h4 anchorWithHideOnScrollNavbar_3R7-" id="12-视口"></a>1.2 视口<a class="hash-link" href="#12-视口" title="Direct link to heading">#</a></h4><p><img src="https://user-images.githubusercontent.com/17002181/129689136-b9ab7dd0-1746-413a-afac-dbcd7d39b426.png" alt="image"></p><p><strong>视口(viewport)</strong></p><p>视口一般是指用户访问页面时,当前的可视区域范围。通过滚动条滑动,视口可以显示页面的其他部分。在 PC 端上,<code><html></code> 元素的宽度被设置为 100% 时,等同于视口大小,等同于浏览器的窗口大小。通过 <code>document.documentElement.clientWidth</code> 或 <code>window.innerWidth</code> 可以获取视口宽度。CSS 布局基于视口大小进行计算。</p><p>由于移动设备尺寸较小,如果基于浏览器窗口大小的视口进行布局,会导致一些没有适配过移动设备样式的站点布局错乱,用户体验差。为了让移动端也能正常显示未适配移动设备的页面,从而引入布局视口和视觉视口的概念。</p><p><strong>布局视口(layout viewport)</strong></p><p>布局视口的宽度默认为 980px,通常比物理屏幕宽。CSS 布局会基于布局视口进行计算。移动设备的浏览器基于虚拟的布局视口去渲染网页,并将对应的渲染结果缩小以便适应设备实际宽度,从而可以完整的展示站点内容且不破坏布局结构。</p><p><strong>视觉视口(visual viewport)</strong></p><p>视觉视口是布局视口的当前可见部分。用户可以通过缩放来查看页面内容,从而改变视觉视口,但不影响布局视口。</p><h3><a aria-hidden="true" tabindex="-1" class="anchor anchor__h3 anchorWithHideOnScrollNavbar_3R7-" id="2-使用-viewport-元标签配置视口"></a>2. 使用 viewport 元标签配置视口<a class="hash-link" href="#2-使用-viewport-元标签配置视口" title="Direct link to heading">#</a></h3><p>开发者可以通过 <code><meta name="viewport"></code> 对移动端的布局视口进行设置。如果不进行 viewport 元标签的设置,可能会导致开发者设定的较小宽度的媒体查询永远不会被使用,因为默认的布局视口宽度为 980px。</p><div class="codeBlockContainer_K1bP"><div class="codeBlockContent_hGly html"><pre tabindex="0" class="prism-code language-html codeBlock_23N8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_39YC"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic"><!-- width 属性控制视口的大小。device-width 值指代设备屏幕宽度。 --></span><span class="token plain"></span></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"><!-- initial-scale 属性控制页面首次加载时的缩放级别。--></span><span class="token plain"></span></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">meta</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">name</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">viewport</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">content</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">width=device-width, initial-scale=1.0</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag" style="color:#00009f"> </span><span class="token tag punctuation" style="color:#393A34">/></span></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_Ue-o clean-btn">Copy</button></div></div><h3><a aria-hidden="true" tabindex="-1" class="anchor anchor__h3 anchorWithHideOnScrollNavbar_3R7-" id="3-使用现代响应式布局方案"></a>3. 使用现代响应式布局方案<a class="hash-link" href="#3-使用现代响应式布局方案" title="Direct link to heading">#</a></h3><p>除了使用浮动布局和百分比布局外,目前比较常见的是使用 Flexbox 或 CSS Grid 来实现灵活的网格布局。可以根据以下条件来选择布局方案:</p><ol><li><p><strong>需要一维还是二维布局</strong>:Flexbox 基于一条主轴方向进行布局。CSS Grid 可划分为行和列进行布局。如果只需要按照行或列进行布局则使用 Flexbox;如果需要同时按照行和列控制布局则使用 CSS Grid。</p></li><li><p><strong>专注布局结构还是内容流</strong>:Flexbox 专注于内容流。Flex Item 的宽度或高度由项目中的内容决定。Flex Item 根据其内部内容和可用空间进行增长和缩小。CSS Grid 专注于精确的内容布局结构规则。每个 Grid Item 都是一个网格单元,沿水平轴和垂直轴排列。如果允许内容灵活的分配空间则使用 Flexbox;如果需要准确控制布局中项目的位置则使用 CSS Grid。</p></li></ol><p><img src="https://user-images.githubusercontent.com/17002181/129393911-324a2f65-30c3-423d-9825-cc3b4d5e3d9e.png" alt="image"></p><h3><a aria-hidden="true" tabindex="-1" class="anchor anchor__h3 anchorWithHideOnScrollNavbar_3R7-" id="4-使用媒体查询media-queries"></a>4. 使用媒体查询(Media Queries)<a class="hash-link" href="#4-使用媒体查询media-queries" title="Direct link to heading">#</a></h3><p>媒体查询允许开发者根据设备类型和特征(如屏幕分辨率或浏览器视口宽度)来按需设置样式。</p><div class="codeBlockContainer_K1bP"><div class="codeBlockContent_hGly css"><pre tabindex="0" class="prism-code language-css codeBlock_23N8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_39YC"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">/* 当浏览器宽度至少在 600px 及以上时 */</span><span class="token plain"></span></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token atrule rule" style="color:#00a4db">@media</span><span class="token atrule" style="color:#00a4db"> screen </span><span class="token atrule keyword" style="color:#00009f">and</span><span class="token atrule" style="color:#00a4db"> </span><span class="token atrule punctuation" style="color:#393A34">(</span><span class="token atrule property" style="color:#36acaa">min-width</span><span class="token atrule punctuation" style="color:#393A34">:</span><span class="token atrule" style="color:#00a4db"> </span><span class="token atrule number" style="color:#36acaa">600</span><span class="token atrule unit" style="color:#00a4db">px</span><span class="token atrule punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token selector class" style="color:#00009f">.hzfe</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">/* 对 .hzfe 应用某些样式 */</span><span class="token plain"></span></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block">
|
||
</span></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">/* 当设备 DPR 为2时的样式 */</span><span class="token plain"></span></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token atrule rule" style="color:#00a4db">@media</span><span class="token atrule" style="color:#00a4db"> screen </span><span class="token atrule keyword" style="color:#00009f">and</span><span class="token atrule" style="color:#00a4db"> </span><span class="token atrule punctuation" style="color:#393A34">(</span><span class="token atrule property" style="color:#36acaa">-webkit-min-device-pixel-ratio</span><span class="token atrule punctuation" style="color:#393A34">:</span><span class="token atrule" style="color:#00a4db"> </span><span class="token atrule number" style="color:#36acaa">2</span><span class="token atrule punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token selector class" style="color:#00009f">.border-1</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token property" style="color:#36acaa">border-width</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0.5</span><span class="token unit">px</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_Ue-o clean-btn">Copy</button></div></div><h3><a aria-hidden="true" tabindex="-1" class="anchor anchor__h3 anchorWithHideOnScrollNavbar_3R7-" id="5-使用相对单位"></a>5. 使用相对单位<a class="hash-link" href="#5-使用相对单位" title="Direct link to heading">#</a></h3><p>移动端开发需要面对十分繁杂的终端设备尺寸。除了使用响应式布局、媒体查询等方案之外,在对元素进行布局时,一般会使用相对单位来获得更多的灵活性。</p><p><strong>rem</strong></p><p>根据 W3C 规范可知,1rem 等同于根元素 html 的 font-size 大小。</p><p>由于早期 vw、vh 兼容性不佳,一个使用广泛的移动端适配方案 flexible 是借助 rem 来模拟 vw 特性实现移动端适配。在设计与开发时,通常会约定某一种尺寸为开发基准。开发者可以利用工具(如 px2rem)进行绝对单位 px 和其他 rem 单位的自动换算,然后利用 flexible 脚本动态设置 html 的字体大小和<code><meta name="viewport"></code>。</p><p><strong>vw/vh</strong></p><p>由于目前 vw、vh 相关单位获得了更多浏览器的支持,可以直接使用 vw、vh 单位进行移动端开发。</p><p>同理于 flexible 方案,使用 vw、vh 也需要对设计稿中的尺寸进行换算,将 px 转换为 vw 值,常见的工具如 postcss-px-to-viewport 等可以满足需求。</p><p><img src="https://user-images.githubusercontent.com/17002181/129445686-b8265558-c270-4ad8-b8f9-e9773d00e923.png" alt="image"></p><h3><a aria-hidden="true" tabindex="-1" class="anchor anchor__h3 anchorWithHideOnScrollNavbar_3R7-" id="6-使用响应式图片"></a>6. 使用响应式图片<a class="hash-link" href="#6-使用响应式图片" title="Direct link to heading">#</a></h3><p>展示图片时,可以在 picture 元素中定义零或多个 source 元素和一个 img 元素,以便为不同的显示/设备场景提供图像的替代版本。从而使得图片内容能够灵活响应不同的设备,避免出现图片模糊或视觉效果差以及使用过大图片浪费带宽的问题。</p><p>source 元素可以按需配置 srcset、media、sizes 等属性,以便用户代理为不同媒体查询范围或像素密度比的设备配置对应的图片资源。如果没有找到匹配的图像或浏览器不支持 picture 元素,则使用 img 元素作为回退方案。</p><div class="codeBlockContainer_K1bP"><div class="codeBlockContent_hGly html"><pre tabindex="0" class="prism-code language-html codeBlock_23N8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_39YC"><span class="token-line" style="color:#393A34"><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">picture</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain"></span></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">source</span><span class="token tag" style="color:#00009f"></span></span><span class="token-line" style="color:#393A34"><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">srcset</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">hzfe-avatar-desktop.png, hzfe-avatar-desktop-2x.png 2x</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag" style="color:#00009f"></span></span><span class="token-line" style="color:#393A34"><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">media</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">(min-width: 990px)</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag" style="color:#00009f"></span></span><span class="token-line" style="color:#393A34"><span class="token tag" style="color:#00009f"> </span><span class="token tag punctuation" style="color:#393A34">/></span><span class="token plain"></span></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">source</span><span class="token tag" style="color:#00009f"></span></span><span class="token-line" style="color:#393A34"><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">srcset</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">hzfe-avatar-tablet.png, hzfe-avatar-tablet-2x.png 2x</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag" style="color:#00009f"></span></span><span class="token-line" style="color:#393A34"><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">media</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">(min-width: 750px)</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag" style="color:#00009f"></span></span><span class="token-line" style="color:#393A34"><span class="token tag" style="color:#00009f"> </span><span class="token tag punctuation" style="color:#393A34">/></span><span class="token plain"></span></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">source</span><span class="token tag" style="color:#00009f"></span></span><span class="token-line" style="color:#393A34"><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">srcset</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">hzfe-avatar-mobile.png, hzfe-avatar-mobile-2x.png 2x</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag" style="color:#00009f"></span></span><span class="token-line" style="color:#393A34"><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">media</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">(min-width: 375px)</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag" style="color:#00009f"></span></span><span class="token-line" style="color:#393A34"><span class="token tag" style="color:#00009f"> </span><span class="token tag punctuation" style="color:#393A34">/></span><span class="token plain"></span></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">img</span><span class="token tag" style="color:#00009f"></span></span><span class="token-line" style="color:#393A34"><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">srcset</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">hzfe-avatar.png, hzfe-avatar-2x.png 2x</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag" style="color:#00009f"></span></span><span class="token-line" style="color:#393A34"><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">src</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">hzfe-avatar.png</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag" style="color:#00009f"></span></span><span class="token-line" style="color:#393A34"><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">alt</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">hzfe-default-avatar</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag" style="color:#00009f"></span></span><span class="token-line" style="color:#393A34"><span class="token tag" style="color:#00009f"> </span><span class="token tag punctuation" style="color:#393A34">/></span><span class="token plain"></span></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token tag punctuation" style="color:#393A34"></</span><span class="token tag" style="color:#00009f">picture</span><span class="token tag punctuation" style="color:#393A34">></span></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_Ue-o clean-btn">Copy</button></div></div><h3><a aria-hidden="true" tabindex="-1" class="anchor anchor__h3 anchorWithHideOnScrollNavbar_3R7-" id="7-适配安全区域"></a>7. 适配安全区域<a class="hash-link" href="#7-适配安全区域" title="Direct link to heading">#</a></h3><p>由于手机厂商各有特色,目前手机上常见有圆角(corners)、刘海(sensor housing)和小黑条(Home Indicator)等特征。为保证页面的显示效果不被这些特征遮盖,需要把页面限制在安全区域范围内。</p><div class="codeBlockContainer_K1bP"><div class="codeBlockContent_hGly html"><pre tabindex="0" class="prism-code language-html codeBlock_23N8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_39YC"><span class="token-line" style="color:#393A34"><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">meta</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">name</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">viewport</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">content</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">initial-scale=1, viewport-fit=cover</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag" style="color:#00009f"> </span><span class="token tag punctuation" style="color:#393A34">/></span></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_Ue-o clean-btn">Copy</button></div></div><p>设置 <code>viewport-fit=cover</code> 后,按需借助以下预设的环境变量,对元素应用 padding,从而确保它们不会被一些以上特征遮盖:</p><ul><li>safe-area-inset-left</li><li>safe-area-inset-right</li><li>safe-area-inset-top</li><li>safe-area-inset-bottom</li></ul><div class="codeBlockContainer_K1bP"><div class="codeBlockContent_hGly css"><pre tabindex="0" class="prism-code language-css codeBlock_23N8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_39YC"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">/* 例子:兼容刘海屏 */</span><span class="token plain"></span></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token selector" style="color:#00009f">body</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">/* constant 函数兼容 iOS 11.2 以下*/</span><span class="token plain"></span></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token property" style="color:#36acaa">padding-top</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">constant</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">safe-area-inset-top</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">/* env 函数兼容 iOS 11.2 */</span><span class="token plain"></span></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token property" style="color:#36acaa">padding-top</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">env</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">safe-area-inset-top</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_Ue-o clean-btn">Copy</button></div></div><h2><a aria-hidden="true" tabindex="-1" class="anchor anchor__h2 anchorWithHideOnScrollNavbar_3R7-" id="参考资料"></a>参考资料<a class="hash-link" href="#参考资料" title="Direct link to heading">#</a></h2><ol><li><a href="http://iosres.com/" target="_blank" rel="noopener noreferrer">iOSRes</a></li><li><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Viewport_concepts" target="_blank" rel="noopener noreferrer">Viewport concepts</a></li><li><a href="https://www.quirksmode.org/mobile/viewports.html" target="_blank" rel="noopener noreferrer">A tale of two viewports</a></li><li><a href="https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Responsive_Design" target="_blank" rel="noopener noreferrer">Responsive Design</a></li><li><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout/Relationship_of_Grid_Layout" target="_blank" rel="noopener noreferrer">Relationship of grid layout to other layout methods</a></li><li><a href="https://webkit.org/blog/7929/designing-websites-for-iphone-x/" target="_blank" rel="noopener noreferrer">Designing Websites for iPhone X</a></li></ol></div></article><nav class="pagination-nav docusaurus-mt-lg" aria-label="Docs pages navigation"><div class="pagination-nav__item"><a class="pagination-nav__link" href="/awesome-interview/book3/js-ts-interface-type"><div class="pagination-nav__sublabel">Previous</div><div class="pagination-nav__label">« 基础:TypeScript 中的 Interface 和 Type Alias</div></a></div><div class="pagination-nav__item pagination-nav__item--next"><a class="pagination-nav__link" href="/awesome-interview/book3/network-http-1-2"><div class="pagination-nav__sublabel">Next</div><div class="pagination-nav__label">网络:HTTP2 和 HTTP1.1 的对比 »</div></a></div></nav></div></div><div class="col col--3"><div class="tableOfContents_35-E thin-scrollbar"><ul class="table-of-contents table-of-contents__left-border"><li><a href="#相关问题" class="table-of-contents__link">相关问题</a></li><li><a href="#回答关键点" class="table-of-contents__link">回答关键点</a></li><li><a href="#知识点深入" class="table-of-contents__link">知识点深入</a><ul><li><a href="#1-相关概念" class="table-of-contents__link">1. 相关概念</a></li><li><a href="#2-使用-viewport-元标签配置视口" class="table-of-contents__link">2. 使用 viewport 元标签配置视口</a></li><li><a href="#3-使用现代响应式布局方案" class="table-of-contents__link">3. 使用现代响应式布局方案</a></li><li><a href="#4-使用媒体查询media-queries" class="table-of-contents__link">4. 使用媒体查询(Media Queries)</a></li><li><a href="#5-使用相对单位" class="table-of-contents__link">5. 使用相对单位</a></li><li><a href="#6-使用响应式图片" class="table-of-contents__link">6. 使用响应式图片</a></li><li><a href="#7-适配安全区域" class="table-of-contents__link">7. 适配安全区域</a></li></ul></li><li><a href="#参考资料" class="table-of-contents__link">参考资料</a></li></ul></div></div></div><div class="row"><div class="col"><div class="react-utterences"><div>Loading script...</div></div></div><div class="col col--3"></div></div></div></main></div></div></div>
|
||
<script src="/awesome-interview/assets/js/runtime~main.e4536af0.js"></script>
|
||
<script src="/awesome-interview/assets/js/main.52f9823f.js"></script>
|
||
</body>
|
||
</html> |