前端CSS網頁佈局新技術(雙屏和摺疊屏手機)解決方案

三星 Galaxy Fold 和 Surface Duo 以及華爲mate X等系列摺疊屏手機問世至今已有三年多的時間。此後,三星 Galaxy Z Fold 3 和 Galaxy Z Flip 3、華爲mate X2S、榮耀magic V系列等手機均已上市。可摺疊設備可供購買,目前正在被消費者使用,隨之而來的是我們作爲開發人員可以開始探索這種新型設備和響應式設計的下一個發展的機會。

 

這些 Web 平臺功能與現有概念(例如視口和媒體查詢)集成,因此開發人員和設計人員可以花更多時間思考如何利用兩個顯示器來創建增強體驗,而不是學習一組新代碼來構建它們。

使用新的 CSS 媒體功能檢測可摺疊設備

雙屏和可摺疊設備只是響應式設計的下一步,因此它們被視爲另一個響應式設計目標,我們可以使用媒體功能爲其設計樣式。我們今天已經使用媒體功能和查詢來定位臺式機、平板電腦和手機,現在我們擁有 CSS Viewport Segments 媒體功能來定位我們的可摺疊和雙屏設備。

horizontal-viewport-segments

視口分段媒體查詢可以有兩個值。第一個是
horizontal-viewport-segments,這表示設備鉸鏈垂直且視口被硬件鉸鏈拆分或摺疊成列時的設備狀態。

 


horizonal-viewport-segment鉸鏈處於垂直摺疊姿勢時,目標是設備。

爲了專門爲這種方向的可摺疊設備提供樣式,我們將編寫以下內容:

@media (horizontal-viewport-segments: 2) {
// Styles specific to the device in this orientation
}

整數表示設備方向中存在的視口數量。當設備像一本書一樣處於垂直摺疊姿勢時,我們在水平方向有兩個不同的視口,在垂直方向只有一個視口。

我們還可以結合我們的媒體查詢來定位雙屏設備和某些視口寬度,以提供特定的樣式:

@media (horizontal-viewport-segments: 2) and (min-width: 540px) {
   body {
       background: yellow;
  }
}

vertical-viewport-segments

我們的視口分段媒體功能的第二個值是
vertical-viewport-segments,這是設備鉸鏈水平時設備的狀態,並且硬件鉸鏈將我們的視口分成行。

 


vertical-viewport-segments目標設備處於水平摺疊姿勢。

要定位在這個方向旋轉的設備,我們將使用以下代碼:

@media (vertical-viewport-segments: 2) {
  // Styles specific to the device in this orientation
}

使用 JavaScript 檢測可摺疊設備

在某些情況下,您可能無法或不想使用 CSS 媒體查詢來檢測您的用戶是否在可摺疊設備上,這就是 JavaScript API 的用武之地。最初,提出了一個名爲 Windows Segments Enumeration 的全新 API ,但在開發者社區通過原始試驗獲得反饋後,在現有的Visual Viewport API 草案規範的基礎上構建更有意義。

視口段屬性

視口段表示位於彼此相鄰的單獨顯示器上的窗口區域。要檢測雙屏設備,您可以使用以下代碼查詢 segments 屬性:

const segments = window.visualViewport.segments;

此查詢返回的值將是一個數組DOMRects,指示有多少視口。如果只有一個視口段,則查詢將返回null,並以這種方式實現以防止將來出現兼容性問題,以免開發人員開始使用visualViewport.segments[0]針對單屏設備。

在雙屏設備上,查詢將返回 2 DOMRects,表示當瀏覽器窗口跨越摺疊時可用的 2 個視口。

我們存儲在segments常量中的這個值是查詢屬性時設備狀態的不可變快照,如果瀏覽器窗口調整大小或設備旋轉,之前檢索到的視口段不再有效,需要查詢再次通過調整大小或方向事件(或兩者)。

如果您調整瀏覽器窗口的大小以僅跨越一個顯示區域,我們將觸發調整大小事件。

如果您旋轉設備,這將觸發調整大小和方向事件,您可以使用這些事件再次查詢屬性以獲取瀏覽器顯示區域的當前狀態。

window.addEventListener("resize", function() {
   const segments = window.visualViewport.segments;
   console.log(segments.length); *// 1*
});

何時使用 JAVASCRIPT API 與 CSS 媒體功能來檢測 設備

CSS 媒體功能和 JavaScript 段屬性都將檢測雙屏設備,但 JavaScript 屬性最好在沒有使用 CSS 時使用,當您在 Canvas2D 和 WebGL 中處理對象時可能會發生這種情況。例如,您正在開發的遊戲可以同時利用兩個屏幕。

使用 CSSenv()變量

除了 CSS 媒體功能之外,還引入了六個新的 CSS 環境變量,以幫助開發人員計算顯示區域的幾何形狀,計算鉸鏈區域在被 Surface Duo 等物理硬件功能遮擋時的幾何形狀,以及它們還可用於幫助將內容放置在每個顯示區域的邊界內。

六個新的環境變量如下:

  • env(viewport-segment-width <x> <y>);
  • env(viewport-segment-height <x> <y>);
  • env(viewport-segment-top <x> <y>);
  • env(viewport-segment-left <x> <y>);
  • env(viewport-segment-bottom <x> <y>);
  • env(viewport-segment-right <x> <y>);

x和位置表示由分隔每個視口段的硬件功能創建的y二維網格,座標0,0從左上段開始。

 

當您的設備處於垂直摺疊姿勢且視口並排時,左側的視口段將由 表示env(viewport-segment-width 0 0),而右側的視口段將由 表示env(viewport-segment-width 1 0)。如果您將設備轉換爲水平摺疊姿勢,視口堆疊,頂部將由 表示env(viewport-segment-height 0 0),底部視口由表示env(viewport-segment-height 0 1)。

使用env(viewport-segment-width)andenv(viewport-segment-width)時,除了索引之外,我們還可以設置一個後備值,如下所示:

env(viewport-segment-width 0 0, 100%);

但是這個額外的後備值是可選的,由作者自行決定,如果他們想包含它。

計算鉸鏈寬度

當您的設備的鉸鏈被硬件功能遮擋時,您可以使用提供的環境變量來計算它。

 

我們可以使用環境變量計算設備鉸鏈。

在我們的示例中,我們有一個處於垂直姿勢的設備,並且想要找到鉸鏈寬度,這樣就不會遮擋任何內容。我們將從左顯示器的右視口段中減去右顯示器的左視口段:

calc(env(viewport-segment-left 1 0) - env(viewport-segment-right 0 0));

使用 CSSenv()變量 放置內容

我們可以使用 CSS 環境變量在顯示區域邊界內放置內容,如果您想將內容直接放置在鉸鏈或摺疊處,這些特別有用。

在下面的示例中,我們將在左側第一個顯示區域的鉸鏈上直接放置圖像。該區域是視口的右側部分,因此我們將使用viewport-segment-right以下代碼放置它:

img {
  max-width: 400px;
}

@media (horizontal-viewport-segments: 2) {
  img {
      position: absolute;
      left: env(viewport-segment-right 0 0);
  }
}

如果我們在 Surface Duo 模式下在 Edge 開發人員工具中模擬我們的屏幕,我們將獲得以下佈局:

 

最初使用環境變量將圖像放置在我們的佈局中會將其放置在錯誤的顯示區域中。

這不是我們想要的。圖像應位於左側的顯示區域中。

因爲圖像是使用屬性絕對定位的left,所以圖像的左邊緣最終與viewport-segment-right顯示區域對齊。

然後,我們需要從環境變量中減去圖像的寬度,以使圖像與正確的鉸鏈邊緣對齊:

img {
   max-width: 400px;
}

@media (horizontal-viewport-segments: 2) {
   img {
       position: absolute;
       left: calc(env(viewport-segment-right 0 0) - 400px);
  }
}

 

從視口段中減去圖像寬度會將其沿左側顯示中的鉸鏈放置。

現在我們將圖像放置在我們想要的位置。有關如何沿鉸鏈對齊項目的其他示例,您可以查看這個簡單的盒子演示。打開Edge Developer Tools>Device Emulation然後選擇Surface Duo並確保您Duo emulation處於校正方向姿勢。

把它們放在一起:讓我們構建一個適應雙屏設備的食譜頁面

作爲一個在做飯時經常使用手機的人,當我在我的雙屏設備上時會適應的食譜網站會非常有幫助。讓我們來看看如何考慮爲它調整一個單獨的食譜頁面。

我想考慮我將如何分塊我的主要內容。通常情況下,我至少會看到食譜標題、製作的份量、烹飪需要多長時間、一張或多張圖片、配料以及製作菜餚的步驟。

當我畫出我的線框時,我得到以下信息:

 

桌面上食譜頁面的標準佈局

我希望我的標題和食譜詳細信息在最頂部,然後是一個佔據整個內容寬度的圖像,然後是成分列表和食譜步驟。我不想堆疊後兩個內容組,因爲如果我堆疊它們,成分列表的右側會有很多空白,所以我希望步驟坐在成分旁邊,給我兩列圖片下方。

用於佈局的 CSS 網格或 FLEXBOX?

我知道我想如何在普通桌面屏幕上佈置這個食譜,並且有多種方法可以對這個佈局進行編碼和對內容進行分組,但我如何對其進行分組,以及我想在雙屏上實現什麼佈局在我編碼之前需要考慮設備。根據我爲桌面視圖所做的草圖,我可以使用 flexbox 和 CSS Grid 的組合來實現我想要的佈局,我將成分和步驟分組到一個 flex 容器中。但是讓我勾勒一下我希望我的頁面如何在雙屏上顯示。

 

垂直摺疊位置的可摺疊設備上的理想佈局通過顯示屏將內容分開,因此不會被鉸鏈遮擋。

如果我想在佈局上有更大的靈活性,那麼我不能將我的成分和步驟分組到一個 flex 容器中,否則,無論圖像沒有進入哪一列,都會有很大的空白。

 

如果我只在這個佈局中使用 flexbox,它會產生一些我想避免亂用的間距。

添加我們的內容

我將在桌面和雙屏佈局中只使用 CSS Grid。所以,讓我們構建我們的內容。

<main>
  <section class="recipe">
      <div class="recipe-meta">
          … <!—Contains our recipe title, yield and servings -->
      </div>
      <img src="imgs/pasta.jpg" alt="Pasta carbonara photographed from above on a rustic plate" />
      <div class="recipe-details__ingredients">
          …<!— Contains our ingredients list -->
      </div>
      <div class="recipe-details__preparation">
          … <!— Contains our list of steps to put the ingredients together -->
      </div>
  </section>
</main>

接下來,讓我們構建頁面的結構。我要定義我的網格:我只想要三列,並且我希望它們是容器的相等部分。

.recipe {
display: grid;
grid-template-columns: repeat(3, 1fr);

接下來,我將定義我的行,並且我將使用grid-auto-rowswith minmax,這樣我的行是最小的,175px但可以增長到最大內容高度的最大值。

grid-auto-rows: minmax(175px, max-content);

然後我將添加更多屬性: my grip-gap、我的最大內容寬度和一個邊距,以使我的佈局在頁面上居中。

grid-gap: 1rem;
max-width: 64rem;
margin: 0 auto;
}

然後,我將把我的內容放入我定義的網格中:

.recipe-meta {
   grid-column: 1 / 4;
}

.recipe-meta p {
   margin: 0;
}

img {
   width: 100%;
   grid-column: 1 / 4;
}

.recipe-details__ingredients {
   grid-row: 3;
}

.recipe-details__preparation {
   grid-column: 2 / 4;
   grid-row: 3;
}

這將根據我的草圖爲我提供佈局:

 

佈局在桌面上按預期呈現

偉大的!但是我的雙屏佈局呢?讓我們深入瞭解我們的horizontal-viewport媒體功能和雙屏網格。

使用媒體查詢和調整容器佈局

首先,這是我現在在雙屏上的佈局:

 

在沒有實現任何雙屏代碼的情況下,如果用戶想要將瀏覽器跨過兩個顯示器,那麼頁面將是這樣的。

如果我們向下滾動:

 

如果用戶選擇跨越兩個顯示器,則內容會被鉸鏈遮擋。

不是很好。我們的內容被鉸鏈遮住了,所以讓我開始重新定義我的網格。

對於我的網格列,我仍將使用三列,但我希望一列佔據左側的第一個視口段,另外兩列佔據右側視口段,因此我將使用我的 CSS環境變量env(viewport-segment-width 0 0)告訴瀏覽器,對於我的第一列,我希望它佔據第一個顯示區域的整個視口。

@media (horizontal-viewport-segments: 2) {

/* Body styles for smaller screens */
body {
       font: 1.3em/1.8 base, 'Playfair Display', serif;
       margin: 0;
  }

.recipe {
   grid-template-columns: env(viewport-segment-width 0 0 1fr 1fr;
   grid-template-rows: repeat(2, 175px) minmax(175px, max-content);
}

}

對於我的行,我希望在放置上更靈活一點,所以我將重複兩行175px,這是關於帶有配方標題、產量和時間信息的容器的高度,之後的行應該匹配我最初在網格中定義的內容。

如果我在 DevTools 中檢查我的設計,我可以看到我在配方容器上設置的width和margin最初將我想要與我的視口段對齊的網格線推到正確的視口段中。

 

添加我的代碼後,我的內容不再被遮擋,但仍需要一些間距調整。

要重置它,我將重置我的marginand max-width。

@media (horizontal-viewport-segments: 2) {

.recipe {
   grid-template-columns: env(viewport-segment-width 0 0) 1fr 1fr;
   grid-template-rows: repeat(2, 175px) minmax(175px, max-content);
   margin: 0;
   max-width: 100%;
}

}

 

重置我的邊距和填充會掩蓋右側顯示中的內容。

現在我要把我的內容放在網格中並調整我的佈局。

.recipe-meta {
   grid-column: 1 / 2;
   padding: 0 2rem;
}

img {
   grid-column: 2 / 4;
   grid-row: 1 / 3;

   width: 100%;
   height: 100%;
   object-fit: cover;
   /* necessary to keep the image within the grid lines */
}

.recipe-details__ingredients {
   grid-row: 2;
   padding: 0 2rem;
}

.recipe-details__preparation {
   grid-column: 2 / 4;
   grid-row: 3;
   padding: 0 2rem 0 3rem;
}

我已經對內容應用了填充,除了我決定要跨越整個視口的圖像。對於圖像下方的內容,由於從物理鉸鏈下方開始的網格線的性質,我想添加額外的填充,因此它看起來左側的填充與其他帶有填充的項目相同。如果我不添加額外的,它會落得太靠近鉸鏈。因爲我已經有一個 grid-gap1rem並且我想將 padding 加倍,所以我將添加3rem而不是4rem爲我們提供雙屏設備上的最終佈局:

 

我可以重新添加尺寸更合適的填充來顯示內容,因此它不會在帶有物理鉸鏈的設備上被遮擋。

只需對我們的 CSS 進行一些小的調整並使用其中一項新的媒體功能,我們就有了一個適應雙屏設備的佈局。要查看體驗,請前往此處的 Edge 演示站點或基於 Chromium 的瀏覽器,然後打開瀏覽器開發人員工具以查看 Surface Duo 仿真。如果您在 Chrome 中打開該站點,請確保在 下啓用了實驗性網絡平臺功能標誌chrome://flags,以便演示正確顯示。

單屏響應式設計細節

爲了確保我們考慮到小型單屏設備,我爲手機佈局選擇的代碼使用了 flexbox 並將所有內容放在一個列中:

@media (max-width: 48rem) {

   body {
       font: 1.3em/1.8 base, 'Playfair Display', serif;
  }

   .recipe-details {
       display: flex;
       flex-direction: column;
  }

}

API 瀏覽器可用性和無設備測試

默認情況下,這些雙屏 API 在 Microsoft Edge 和 Android 上的 Edge 中可用,從版本 97 開始。這些計劃很快就會出現在其他 Chromium 瀏覽器中,但具體時間尚未確定。要在 Chrome 中啓用這些 API,請轉到chrome://flags並啓用實驗性網絡平臺功能。

雖然這些是相對較新的設備,但許多現在已經進入第二代和第三代,因此公司正在投資它們。如果您無法使用物理設備,最好的測試方法是使用瀏覽器開發工具。我已經在仿真工具和 Surface Duo 上測試了我的網站,Duo 的仿真工具似乎是相同的。我的設計在設備上的外觀與在 DevTools 中的外觀相同。它使構建和設計雙屏設備就像開發桌面和單屏移動設備一樣容易。

如果您使用的是不支持這些 API 的桌面或設備,則可以爲 Visual Viewport Segments 屬性提供一個 polyfill。CSS 媒體查詢沒有 API。目前,市場上的雙屏設備都是基於安卓的,這些API計劃在安卓上可用的基於Chromium的瀏覽器中。

如果可摺疊設備上的瀏覽器不支持這些功能,您可以使用 polyfill 或確保您的網站在小單屏上仍能很好地呈現,因爲用戶可以靈活選擇如何在雙屏上顯示網站屏幕設備。他們可以跨兩個顯示器跨越一個網站,或者他們可以選擇讓它跨一個顯示器,如果他們選擇後者,它將像在平板電腦或手機上一樣顯示。即使您的網站沒有雙屏實現,用戶仍然可以選擇單顯示視圖。雙屏 API 提供了一種方法來逐步增強擁有設備的用戶的體驗。

結束

雙屏設備只是響應式設計的下一個發展方向。如果您有 PWA 或網站,可用的 API 可以無縫集成到您現有的代碼庫中。還有其他方法可以爲雙屏設備構建應用程序,您可以在Surface Duo 文檔
https://docs.microsoft.com/en-us/dual-screen/中查看這些方法。這是在網絡上進行佈局的激動人心的時刻,雙屏提供了獲得更多創意的機會。

爲幫助到一部分同學不走彎路,真正達到一線互聯網大廠前端項目研發要求,首次實力寵粉,打造了《30天挑戰學習計劃》,內容如下:

HTML/HTML5,CSS/CSS3,JavaScript,真實企業項目開發,雲服務器部署上線,從入門到精通

  • PC端項目開發(1個)
  • 移動WebApp開發(2個)
  • 多端響應式開發(1個)

共4大完整的項目開發 !一行一行代碼帶領實踐開發,實際企業開發怎麼做我們就是怎麼做。從學習一開始就進入工作狀態,省得浪費時間。

從學習一開始就同步使用 Git 進行項目代碼的版本的管理,Markdown 記錄學習筆記,包括真實大廠項目的開發標準和設計規範,命名規範,項目代碼規範,SEO優化規範

從藍湖UI設計稿 到 PC端,移動端,多端響應式開發項目開發

  • 真機調試,雲服務部署上線;
  • Linux環境下 的 Nginx 部署,Nginx 性能優化;
  • Gzip 壓縮,HTTPS 加密協議,域名服務器備案,解析;
  • 企業項目域名跳轉的終極解決方案,多網站、多系統部署;
  • 使用 使用 Git 在線項目部署;

這些內容在《30天挑戰學習計劃》中每一個細節都有講到,包含視頻+圖文教程+項目資料素材等。只爲實力寵粉,真正一次掌握企業項目開發必備技能,不走彎路 !

過程中【不涉及】任何費用和利益,非誠勿擾 。

如果你沒有添加助理老師微信,可以添加下方微信,說明要參加30天挑戰學習計劃,來自博客園!老師會邀請你進入學習,並給你發放相關資料。

30 天挑戰學習計劃 Web 前端從入門到實戰 | arry老師的博客-艾編程

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章