媒體查詢入門指南

CSS 媒體查詢為你提供了一種方式,僅在瀏覽器和裝置環境與你指定的規則匹配時才應用 CSS,例如“視窗寬度大於 480 畫素”。媒體查詢是響應式 Web 設計的關鍵部分,因為它們允許你根據視窗大小建立不同的佈局,但它們也可以用來檢測執行網站的環境的其他方面,例如使用者是使用觸控式螢幕還是滑鼠。在本課中,你將首先了解媒體查詢中使用的語法,然後繼續在一個工作示例中使用它們,展示如何使一個簡單的設計變得響應式。

先決條件 HTML 基礎知識(學習HTML 簡介),以及對 CSS 工作原理的瞭解(學習CSS 入門CSS 構建塊)。
目標 瞭解如何使用媒體查詢,以及使用它們建立響應式設計的最常見方法。

媒體查詢基礎

最簡單的媒體查詢語法如下所示

css
@media media-type and (media-feature-rule) {
  /* CSS rules go here */
}

它由以下部分組成

  • 媒體型別,它告訴瀏覽器此程式碼適用於哪種媒體(例如,print 或 screen)。
  • 媒體表達式,它是一個規則或測試,必須透過才能應用包含的 CSS。
  • 一組 CSS 規則,如果測試透過且媒體型別正確,則將應用這些規則。

媒體型別

你可以指定的媒體型別包括

  • all
  • print
  • screen

以下媒體查詢僅在列印頁面時將 body 設定為 12pt。在瀏覽器中載入頁面時不會應用它。

css
@media print {
  body {
    font-size: 12pt;
  }
}

注意:這裡的媒體型別不同於所謂的MIME 型別

注意:級別 3 媒體查詢規範中定義了許多其他媒體型別;這些型別已被棄用,應該避免使用。

注意:媒體型別是可選的;如果你在媒體查詢中沒有指定媒體型別,則媒體查詢將預設適用於所有媒體型別。

媒體特性規則

指定型別後,你可以使用規則針對媒體特性。

寬度和高度

我們最常檢測的特性,以便建立響應式設計(並且具有廣泛的瀏覽器支援)是視窗寬度,我們可以使用 min-widthmax-widthwidth 媒體特性,在視窗寬度高於或低於某個特定寬度(或確切寬度)時應用 CSS。

這些特性用於建立響應不同螢幕尺寸的佈局。例如,如果視窗寬度恰好為 600 畫素,則將 body 文字顏色更改為紅色,可以使用以下媒體查詢。

css
@media screen and (width: 600px) {
  body {
    color: red;
  }
}

在瀏覽器中開啟此示例,或檢視原始碼

width(和height)媒體特徵可以用作範圍,因此可以加字首min-max-來表示給定值是最小值或最大值。例如,如果視窗寬度為 600 畫素或更窄,則將顏色設定為藍色,使用max-width

css
@media screen and (max-width: 600px) {
  body {
    color: blue;
  }
}

在瀏覽器中開啟此示例,或檢視原始碼

在實際應用中,使用最小值或最大值對於響應式設計更有用,因此您很少會看到單獨使用widthheight

您可以測試許多其他媒體特徵,儘管媒體查詢規範第 4 級和第 5 級中引入的一些較新特徵的瀏覽器支援有限。每個特徵在 MDN 上都有記錄,以及瀏覽器支援資訊,您可以在使用媒體查詢:語法中找到完整的列表。

方向

一個得到良好支援的媒體特徵是orientation,它允許我們測試縱向或橫向模式。如果裝置處於橫向模式,則更改正文文字顏色,請使用以下媒體查詢。

css
@media (orientation: landscape) {
  body {
    color: rebeccapurple;
  }
}

在瀏覽器中開啟此示例,或檢視原始碼

標準桌面檢視具有橫向方向,而在此方向上效果良好的設計在手機或平板電腦上以縱向模式檢視時可能效果不佳。測試方向可以幫助您建立針對縱向模式裝置最佳化的佈局。

指向裝置的使用

作為第 4 級規範的一部分,引入了hover媒體特徵。此特徵意味著您可以測試使用者是否能夠將滑鼠懸停在元素上,這實際上意味著他們使用的是某種指向裝置;觸控式螢幕和鍵盤導航不會懸停。

css
@media (hover: hover) {
  body {
    color: rebeccapurple;
  }
}

在瀏覽器中開啟此示例,或檢視原始碼

如果我們知道使用者無法懸停,我們可以預設顯示一些互動式功能。對於可以懸停的使用者,我們可能選擇在將滑鼠懸停在連結上時使其可用。

第 4 級中還有pointer媒體特徵。它接受三個可能的值,nonefinecoarsefine指標是像滑鼠或觸控板這樣的東西。它使使用者能夠精確地定位一個小區域。coarse指標是您在觸控式螢幕上的手指。none值表示使用者沒有指向裝置;也許他們只使用鍵盤或語音命令進行導航。

使用pointer可以幫助您設計更好的介面,以響應使用者與螢幕互動的方式。例如,如果您知道使用者正在以觸控式螢幕的方式與裝置互動,則可以建立更大的點選區域。

使用範圍語法

一個常見的例子是檢查視窗寬度是否在兩個值之間

css
@media (min-width: 30em) and (max-width: 50em) {
  /* … */
}

如果您想提高可讀性,可以使用“範圍”語法

css
@media (30em <= width <= 50em) {
  /* … */
}

因此,在這種情況下,當視窗寬度在30em50em之間時,將應用樣式。

更復雜的媒體查詢

對於所有可能的媒體查詢,您可能希望將它們組合起來,或建立查詢列表——任何一個都可能匹配。

“and”邏輯在媒體查詢中

要組合媒體特徵,您可以使用and,就像我們上面使用and來組合媒體型別和特徵一樣。例如,我們可能希望測試min-widthorientation。只有當視窗寬度至少為 600 畫素且裝置處於橫向模式時,正文文字才會變為藍色。

css
@media screen and (min-width: 600px) and (orientation: landscape) {
  body {
    color: blue;
  }
}

在瀏覽器中開啟此示例,或檢視原始碼

“or”邏輯在媒體查詢中

如果您有一組查詢,其中任何一個都可能匹配,那麼您可以用逗號分隔這些查詢。在下面的示例中,如果視窗寬度至少為 600 畫素或裝置處於橫向模式,則文字將變為藍色。如果這兩個條件中的任何一個為真,則查詢匹配。

css
@media screen and (min-width: 600px), screen and (orientation: landscape) {
  body {
    color: blue;
  }
}

在瀏覽器中開啟此示例,或檢視原始碼

“not”邏輯在媒體查詢中

您可以使用not運算子否定整個媒體查詢。這將顛倒整個媒體查詢的含義。因此,在下一個示例中,只有當方向為縱向時,文字才會變為藍色。

css
@media not (orientation: landscape) {
  body {
    color: blue;
  }
}

在瀏覽器中開啟此示例,或檢視原始碼

您還可以使用not來否定特定表示式。

css
@media (not (width < 600px)) and (not (width > 1000px)) {
  body {
    color: blue;
  }
}

如果視窗寬度在 600 和 1000 畫素之間,這將應用樣式。這等效於(600px <= width <= 1000px)

如何選擇斷點

在響應式設計的早期,許多設計師會嘗試針對非常具體的螢幕尺寸。釋出了流行手機和平板電腦螢幕尺寸的列表,以便可以建立與這些視窗完美匹配的設計。

現在有太多裝置,尺寸差異很大,無法實現這一點。這意味著,與其為所有設計針對特定尺寸,不如在內容開始以某種方式中斷的尺寸更改設計。也許行長變得太長,或者一個框起來的側邊欄被擠壓,難以閱讀。這就是您需要使用媒體查詢來更改設計以適應可用空間的最佳點。這種方法意味著,無論使用的裝置的確切尺寸如何,每個範圍都得到了照顧。引入媒體查詢的點被稱為**斷點**。

Firefox DevTools 中的響應式設計模式對於確定這些斷點應該在哪裡非常有用。您可以輕鬆地使視窗變小或變大,以檢視在何處新增媒體查詢並調整設計可以改善內容。

A screenshot of a layout in a mobile view in Firefox DevTools.

主動學習:移動優先響應式設計

總的來說,您可以採取兩種方法進行響應式設計。您可以從桌面或最寬的檢視開始,然後新增斷點,隨著視窗變小,將內容移動到其他位置,或者您可以從最小的檢視開始,隨著視窗變大,添加布局。第二種方法被稱為**移動優先**響應式設計,通常是最佳方法。

對於最小的裝置,檢視通常是簡單的一列內容,就像它在普通流中顯示的一樣。這意味著您可能不需要為小型裝置進行很多佈局——將原始碼排序好,您預設情況下將擁有可讀的佈局。

下面的演練將帶您瞭解這種方法,使用非常簡單的佈局。在生產站點中,您可能需要在媒體查詢中調整更多內容,但是方法完全相同。

演練:一個簡單的移動優先佈局

我們的起點是一個 HTML 文件,其中應用了一些 CSS 來為佈局的各個部分新增背景顏色。

css
* {
  box-sizing: border-box;
}

body {
  width: 90%;
  margin: 2em auto;
  font:
    1em/1.3 Arial,
    Helvetica,
    sans-serif;
}

a:link,
a:visited {
  color: #333;
}

nav ul,
aside ul {
  list-style: none;
  padding: 0;
}

nav a:link,
nav a:visited {
  background-color: rgb(207 232 220 / 20%);
  border: 2px solid rgb(79 185 227);
  text-decoration: none;
  display: block;
  padding: 10px;
  color: #333;
  font-weight: bold;
}

nav a:hover {
  background-color: rgb(207 232 220 / 70%);
}

.related {
  background-color: rgb(79 185 227 / 30%);
  border: 1px solid rgb(79 185 227);
  padding: 10px;
}

.sidebar {
  background-color: rgb(207 232 220 / 50%);
  padding: 10px;
}

article {
  margin-bottom: 1em;
}

我們沒有進行任何佈局更改,但是文件的原始碼是按可讀的方式排序的。這是重要的第一步,它確保如果內容要由螢幕閱讀器讀出,它將是可理解的。

html
<body>
  <div class="wrapper">
    <header>
      <nav>
        <ul>
          <li><a href="">About</a></li>
          <li><a href="">Contact</a></li>
          <li><a href="">Meet the team</a></li>
          <li><a href="">Blog</a></li>
        </ul>
      </nav>
    </header>
    <main>
      <article>
        <div class="content">
          <h1>Veggies!</h1>
          <p></p>
        </div>
        <aside class="related">
          <p></p>
        </aside>
      </article>

      <aside class="sidebar">
        <h2>External vegetable-based links</h2>
        <ul>
          <li></li>
        </ul>
      </aside>
    </main>

    <footer><p>&copy;2019</p></footer>
  </div>
</body>

這個簡單的佈局在移動裝置上也能很好地工作。如果我們在 DevTools 中的響應式設計模式中檢視佈局,我們可以看到它作為站點的簡單移動檢視效果很好。

在瀏覽器中開啟第 1 步,或檢視原始碼

如果您想繼續並實施此示例,請在您的計算機上建立一個step1.html的本地副本。

從這一點開始,開始將響應式設計模式檢視拖得更寬,直到您看到行長變得相當長,並且我們有空間讓導航以水平線顯示。在這裡,我們將新增第一個媒體查詢。我們將使用 em,這意味著如果使用者增加了他們的文字大小,斷點將在與文字大小較小的人相同的行長,但更寬的視窗處發生。

將以下程式碼新增到 step1.html CSS 的底部。

css
@media screen and (min-width: 40em) {
  article {
    display: grid;
    grid-template-columns: 3fr 1fr;
    column-gap: 20px;
  }

  nav ul {
    display: flex;
  }

  nav li {
    flex: 1;
  }
}

此 CSS 在文章內部為我們提供了一個兩列布局,即文章內容和aside元素中的相關資訊。我們還使用 flexbox 將導航放置在一行中。

在瀏覽器中開啟第 2 步,或檢視原始碼

讓我們繼續擴充套件寬度,直到我們感覺有足夠的空間讓側邊欄也形成一個新的列。在媒體查詢內部,我們將main元素做成一個兩列網格。然後,我們需要刪除article上的margin-bottom,以便兩個側邊欄相互對齊,我們將在頁尾頂部新增一個border。通常,這些小調整是您為使設計在每個斷點處看起來不錯而需要做的事情。

同樣,將以下程式碼新增到 step1.html CSS 的底部。

css
@media screen and (min-width: 70em) {
  main {
    display: grid;
    grid-template-columns: 3fr 1fr;
    column-gap: 20px;
  }

  article {
    margin-bottom: 0;
  }

  footer {
    border-top: 1px solid #ccc;
    margin-top: 2em;
  }
}

在瀏覽器中開啟第 3 步,或檢視原始碼

如果您以不同的寬度檢視最終示例,您會看到設計是如何響應的,並作為一列、兩列或三列工作,具體取決於可用寬度。這是一個非常簡單的移動優先響應式設計的示例。

視窗元標籤

如果您檢視上面示例中的 HTML 原始碼,您會看到以下元素包含在文件的頭部

html
<meta name="viewport" content="width=device-width,initial-scale=1" />

這是視窗元標記——它作為一種控制移動瀏覽器渲染內容的方式存在。這是必要的,因為預設情況下,大多數移動瀏覽器會撒謊他們的視窗寬度。非響應式網站在窄視窗中渲染時通常看起來很糟糕,因此移動瀏覽器通常預設情況下使用比實際裝置寬度更寬的視窗寬度(通常為 980 畫素)渲染網站,然後縮小渲染結果以使其適合顯示。

這很好,但這意味著響應式網站將無法按預期工作。如果視窗寬度報告為 980 畫素,那麼移動佈局(例如使用@media screen and (max-width: 600px) { }建立的佈局)將無法按預期渲染。

為了解決這個問題,在您的頁面上包含像上面的視窗元標記這樣的標記會告訴瀏覽器“不要使用 980 畫素的視窗渲染內容——而是使用實際裝置寬度渲染,並設定預設的初始縮放級別,以獲得更好的一致性。”然後,媒體查詢將按預期生效。

您可以在視窗元標記的content屬性中放置許多其他選項——有關更多詳細資訊,請參閱使用視窗元標記來控制移動瀏覽器上的佈局

你真的需要媒體查詢嗎?

Flexbox、Grid 和多列布局都為您提供了建立靈活甚至響應式元件的方法,而無需使用媒體查詢。總是值得考慮這些佈局方法是否可以在不新增媒體查詢的情況下實現您想要的結果。例如,您可能希望有一組卡,它們至少有 200 畫素寬,這些 200 畫素儘可能多地適合主文章。這可以使用網格佈局來實現,根本不使用媒體查詢。

這可以透過以下方法實現

html
<ul class="grid">
  <li>
    <h2>Card 1</h2>
    <p></p>
  </li>
  <li>
    <h2>Card 2</h2>
    <p></p>
  </li>
  <li>
    <h2>Card 3</h2>
    <p></p>
  </li>
  <li>
    <h2>Card 4</h2>
    <p></p>
  </li>
  <li>
    <h2>Card 5</h2>
    <p></p>
  </li>
</ul>
css
.grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 20px;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}

.grid li {
  border: 1px solid #666;
  padding: 10px;
}

在瀏覽器中開啟網格佈局示例,或檢視原始碼

在瀏覽器中開啟示例後,使螢幕變寬或變窄,以檢視列軌道數量的變化。這種方法的好處在於,網格不是在檢視視窗寬度,而是在檢視它為此元件可用的寬度。這似乎很奇怪,在關於媒體查詢的文章末尾建議您可能根本不需要它!但是,在實際操作中,您會發現,良好地使用現代佈局方法,並使用媒體查詢進行增強,將產生最佳效果。

測試你的技能!

您已經讀完了這篇文章,但是您還記得最重要的資訊嗎?您可以在繼續之前找到一個測試來驗證您是否保留了這些資訊——請參閱測試您的技能:響應式網頁設計和媒體查詢

總結

在本課中,您學習了媒體查詢,並瞭解瞭如何將它們應用於實踐,以建立移動優先響應式設計。

您可以使用我們建立的起點來測試更多媒體查詢。例如,也許您可以使用pointer媒體特徵,在檢測到訪問者具有粗指標時更改導航的大小。

您還可以嘗試新增不同的元件,並檢視新增媒體查詢還是使用 Flexbox 或 Grid 這樣的佈局方法是使元件響應的最合適方式。通常情況下,沒有正確或錯誤的方法——您應該嘗試一下,看看哪種方法最適合您的設計和內容。