响应式网页设计 - 媒体查询


什么是媒体查询?

媒体查询是 CSS3 中引入的一种 CSS 技术。

仅在满足特定条件时,它才会使用 @media 规则来引用 CSS 属性块。

实例

如果浏览器窗口是 600px 或更小,则背景颜色为浅蓝色:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  5. <style>
  6. body {
  7. background-color: lightgreen;
  8. }
  9. @media only screen and (max-width: 600px) {
  10. body {
  11. background-color: lightblue;
  12. }
  13. }
  14. </style>
  15. </head>
  16. <body>
  17. <p>请调整浏览器窗口的大小。如果此文档的宽度为 600 像素或更小,背景颜色为“浅蓝色”,否则为“浅绿色”。</p>
  18. </body>
  19. </html>

添加断点

在本教程中稍早前,我们制作了一张包含行和列的网页,但是这张响应式网页在小屏幕上看起来效果并不好。

媒体查询可以帮助您。我们可以添加一个断点,其中设计的某些部分在断点的每一侧会表现得有所不同。

桌面电脑
手机

使用媒体查询在 768px 处添加断点:

当屏幕(浏览器窗口)小于 768px 时,每列的宽度应为 100%:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  5. <style>
  6. * {
  7. box-sizing: border-box;
  8. }
  9. .row::after {
  10. content: "";
  11. clear: both;
  12. display: block;
  13. }
  14. [class*="col-"] {
  15. float: left;
  16. padding: 15px;
  17. }
  18. html {
  19. font-family: "Lucida Sans", sans-serif;
  20. }
  21. .header {
  22. background-color: #9933cc;
  23. color: #ffffff;
  24. padding: 15px;
  25. }
  26. .menu ul {
  27. list-style-type: none;
  28. margin: 0;
  29. padding: 0;
  30. }
  31. .menu li {
  32. padding: 8px;
  33. margin-bottom: 7px;
  34. background-color: #33b5e5;
  35. color: #ffffff;
  36. box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
  37. }
  38. .menu li:hover {
  39. background-color: #0099cc;
  40. }
  41. .aside {
  42. background-color: #33b5e5;
  43. padding: 15px;
  44. color: #ffffff;
  45. text-align: center;
  46. font-size: 14px;
  47. box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
  48. }
  49. .footer {
  50. background-color: #0099cc;
  51. color: #ffffff;
  52. text-align: center;
  53. font-size: 12px;
  54. padding: 15px;
  55. }
  56. /* 针对桌面: */
  57. .col-1 {width: 8.33%;}
  58. .col-2 {width: 16.66%;}
  59. .col-3 {width: 25%;}
  60. .col-4 {width: 33.33%;}
  61. .col-5 {width: 41.66%;}
  62. .col-6 {width: 50%;}
  63. .col-7 {width: 58.33%;}
  64. .col-8 {width: 66.66%;}
  65. .col-9 {width: 75%;}
  66. .col-10 {width: 83.33%;}
  67. .col-11 {width: 91.66%;}
  68. .col-12 {width: 100%;}
  69. @media only screen and (max-width: 768px) {
  70. /* 针对手机: */
  71. [class*="col-"] {
  72. width: 100%;
  73. }
  74. }
  75. </style>
  76. </head>
  77. <body>
  78. <div class="header">
  79. <h2>上海</h2>
  80. </div>
  81. <div class="row">
  82. <div class="col-3 menu">
  83. <ul>
  84. <li>交通</li>
  85. <li>文化</li>
  86. <li>旅游</li>
  87. <li>美食</li>
  88. </ul>
  89. </div>
  90. <div class="col-6">
  91. <h2>欢迎来到上海</h2>
  92. <p>上海市,简称沪,别称申,是中华人民共和国直辖市,中国的经济、金融、贸易和航运中心,世界著名的港口城市,是中国人口第二多的城市。</p>
  93. </div>
  94. <div class="col-3 right">
  95. <div class="aside">
  96. <h2>历史</h2>
  97. <p>最晚在新石器时代,上海地区已经有先民聚居。春秋时代,上海由吴国管辖,战国时代则是楚国领土 ...</p>
  98. <h2>位置</h2>
  99. <p>上海位于中国东部弧形海岸线的正中间,长江三角洲最东部,东临东海,南濒杭州湾,西与江苏、浙江两省相接 ...</p>
  100. <h2>环境</h2>
  101. <p>上海地处江南水乡,并位于长江入海口,亦不处于主要地震带上,因此如地震、洪水以及地质类灾害鲜有发生 ...</p>
  102. </div>
  103. </div>
  104. </div>
  105. <div class="footer">
  106. <p>请调整浏览器窗口的大小,以查看内容如何响应调整大小。</p>
  107. </div>
  108. </body>
  109. </html>

始终移动优先设计

移动优先(Mobile First)指的是在对台式机或任何其他设备进行设计之前,优先针对移动设备进行设计(这将使页面在较小的设备上显示得更快)。

这意味着我们必须在 CSS 中做一些改进。

当宽度小于 768px 时,我们应该修改设计,而不是更改宽度。我们就这样进行了“移动优先”的设计:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  5. <style>
  6. * {
  7. box-sizing: border-box;
  8. }
  9. .row::after {
  10. content: "";
  11. clear: both;
  12. display: table;
  13. }
  14. [class*="col-"] {
  15. float: left;
  16. padding: 15px;
  17. }
  18. html {
  19. font-family: "Lucida Sans", sans-serif;
  20. }
  21. .header {
  22. background-color: #9933cc;
  23. color: #ffffff;
  24. padding: 15px;
  25. }
  26. .menu ul {
  27. list-style-type: none;
  28. margin: 0;
  29. padding: 0;
  30. }
  31. .menu li {
  32. padding: 8px;
  33. margin-bottom: 7px;
  34. background-color: #33b5e5;
  35. color: #ffffff;
  36. box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
  37. }
  38. .menu li:hover {
  39. background-color: #0099cc;
  40. }
  41. .aside {
  42. background-color: #33b5e5;
  43. padding: 15px;
  44. color: #ffffff;
  45. text-align: center;
  46. font-size: 14px;
  47. box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
  48. }
  49. .footer {
  50. background-color: #0099cc;
  51. color: #ffffff;
  52. text-align: center;
  53. font-size: 12px;
  54. padding: 15px;
  55. }
  56. /* 针对手机: */
  57. [class*="col-"] {
  58. width: 100%;
  59. }
  60. @media only screen and (min-width: 768px) {
  61. /* For desktop: */
  62. .col-1 {width: 8.33%;}
  63. .col-2 {width: 16.66%;}
  64. .col-3 {width: 25%;}
  65. .col-4 {width: 33.33%;}
  66. .col-5 {width: 41.66%;}
  67. .col-6 {width: 50%;}
  68. .col-7 {width: 58.33%;}
  69. .col-8 {width: 66.66%;}
  70. .col-9 {width: 75%;}
  71. .col-10 {width: 83.33%;}
  72. .col-11 {width: 91.66%;}
  73. .col-12 {width: 100%;}
  74. }
  75. </style>
  76. </head>
  77. <body>
  78. <div class="header">
  79. <h1>上海</h1>
  80. </div>
  81. <div class="row">
  82. <div class="col-3 menu">
  83. <ul>
  84. <li>交通</li>
  85. <li>文化</li>
  86. <li>旅游</li>
  87. <li>美食</li>
  88. </ul>
  89. </div>
  90. <div class="col-6">
  91. <h1>欢迎来到上海</h1>
  92. <p>上海市,简称沪,别称申,是中华人民共和国直辖市,中国的经济、金融、贸易和航运中心,世界著名的港口城市,是中国人口第二多的城市。</p>
  93. </div>
  94. <div class="col-3 right">
  95. <div class="aside">
  96. <h2>历史</h2>
  97. <p>最晚在新石器时代,上海地区已经有先民聚居。春秋时代,上海由吴国管辖,战国时代则是楚国领土 ...</p>
  98. <h2>位置</h2>
  99. <p>上海位于中国东部弧形海岸线的正中间,长江三角洲最东部,东临东海,南濒杭州湾,西与江苏、浙江两省相接 ...</p>
  100. <h2>环境</h2>
  101. <p>上海地处江南水乡,并位于长江入海口,亦不处于主要地震带上,因此如地震、洪水以及地质类灾害鲜有发生 ...</p>
  102. </div>
  103. </div>
  104. </div>
  105. <div class="footer">
  106. <p>请调整浏览器窗口的大小,来查看内容如何响应调整大小。</p>
  107. </div>
  108. </body>
  109. </html>

另一个断点

您可以添加任意多个断点。我们还会在平板电脑和手机之间插入一个断点。

桌面电脑
平板电脑
手机

为此,我们添加了一个媒体查询(在 600 像素),并为大于 600 像素(但小于 768 像素)的设备添加了一组新类:

请注意,两组类几乎相同,唯一的区别是名称(col- 和 col-s-):

  1. /* 针对手机: */
  2. [class*="col-"] {
  3. width: 100%;
  4. }
  5. @media only screen and (min-width: 600px) {
  6. /* 针对平板电脑: */
  7. .col-s-1 {width: 8.33%;}
  8. .col-s-2 {width: 16.66%;}
  9. .col-s-3 {width: 25%;}
  10. .col-s-4 {width: 33.33%;}
  11. .col-s-5 {width: 41.66%;}
  12. .col-s-6 {width: 50%;}
  13. .col-s-7 {width: 58.33%;}
  14. .col-s-8 {width: 66.66%;}
  15. .col-s-9 {width: 75%;}
  16. .col-s-10 {width: 83.33%;}
  17. .col-s-11 {width: 91.66%;}
  18. .col-s-12 {width: 100%;}
  19. }
  20. @media only screen and (min-width: 768px) {
  21. /* 针对桌面: */
  22. .col-1 {width: 8.33%;}
  23. .col-2 {width: 16.66%;}
  24. .col-3 {width: 25%;}
  25. .col-4 {width: 33.33%;}
  26. .col-5 {width: 41.66%;}
  27. .col-6 {width: 50%;}
  28. .col-7 {width: 58.33%;}
  29. .col-8 {width: 66.66%;}
  30. .col-9 {width: 75%;}
  31. .col-10 {width: 83.33%;}
  32. .col-11 {width: 91.66%;}
  33. .col-12 {width: 100%;}
  34. }

有两组相同的类似乎很奇怪,但是它给了我们机会用 HTML 来决定在每个断点处的列会发生什么:

HTML 实例

对于台式机:

第一和第三部分都会跨越 3 列。中间部分将跨越 6 列。

对于平板电脑:

第一部分将跨越 3 列,第二部分将跨越 9 列,第三部分将显示在前两部分的下方,并将跨越 12 列:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  5. <style>
  6. * {
  7. box-sizing: border-box;
  8. }
  9. .row::after {
  10. content: "";
  11. clear: both;
  12. display: table;
  13. }
  14. [class*="col-"] {
  15. float: left;
  16. padding: 15px;
  17. }
  18. html {
  19. font-family: "Lucida Sans", sans-serif;
  20. }
  21. .header {
  22. background-color: #9933cc;
  23. color: #ffffff;
  24. padding: 15px;
  25. }
  26. .menu ul {
  27. list-style-type: none;
  28. margin: 0;
  29. padding: 0;
  30. }
  31. .menu li {
  32. padding: 8px;
  33. margin-bottom: 7px;
  34. background-color: #33b5e5;
  35. color: #ffffff;
  36. box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
  37. }
  38. .menu li:hover {
  39. background-color: #0099cc;
  40. }
  41. .aside {
  42. background-color: #33b5e5;
  43. padding: 15px;
  44. color: #ffffff;
  45. text-align: center;
  46. font-size: 14px;
  47. box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
  48. }
  49. .footer {
  50. background-color: #0099cc;
  51. color: #ffffff;
  52. text-align: center;
  53. font-size: 12px;
  54. padding: 15px;
  55. }
  56. /* For mobile phones: */
  57. [class*="col-"] {
  58. width: 100%;
  59. }
  60. @media only screen and (min-width: 600px) {
  61. /* 针对平板电脑: */
  62. .col-s-1 {width: 8.33%;}
  63. .col-s-2 {width: 16.66%;}
  64. .col-s-3 {width: 25%;}
  65. .col-s-4 {width: 33.33%;}
  66. .col-s-5 {width: 41.66%;}
  67. .col-s-6 {width: 50%;}
  68. .col-s-7 {width: 58.33%;}
  69. .col-s-8 {width: 66.66%;}
  70. .col-s-9 {width: 75%;}
  71. .col-s-10 {width: 83.33%;}
  72. .col-s-11 {width: 91.66%;}
  73. .col-s-12 {width: 100%;}
  74. }
  75. @media only screen and (min-width: 768px) {
  76. /* 针对桌面: */
  77. .col-1 {width: 8.33%;}
  78. .col-2 {width: 16.66%;}
  79. .col-3 {width: 25%;}
  80. .col-4 {width: 33.33%;}
  81. .col-5 {width: 41.66%;}
  82. .col-6 {width: 50%;}
  83. .col-7 {width: 58.33%;}
  84. .col-8 {width: 66.66%;}
  85. .col-9 {width: 75%;}
  86. .col-10 {width: 83.33%;}
  87. .col-11 {width: 91.66%;}
  88. .col-12 {width: 100%;}
  89. }
  90. </style>
  91. </head>
  92. <body>
  93. <div class="header">
  94. <h2>上海</h2>
  95. </div>
  96. <div class="row">
  97. <div class="col-3 col-s-3 menu">
  98. <ul>
  99. <li>交通</li>
  100. <li>文化</li>
  101. <li>旅游</li>
  102. <li>美食</li>
  103. </ul>
  104. </div>
  105. <div class="col-6 col-s-9">
  106. <h2>欢迎来到上海</h2>
  107. <p>上海市,简称沪,别称申,是中华人民共和国直辖市,中国的经济、金融、贸易和航运中心,世界著名的港口城市,是中国人口第二多的城市。</p>
  108. </div>
  109. <div class="col-3 col-s-12">
  110. <div class="aside">
  111. <h2>历史</h2>
  112. <p>最晚在新石器时代,上海地区已经有先民聚居。春秋时代,上海由吴国管辖,战国时代则是楚国领土 ...</p>
  113. <h2>位置</h2>
  114. <p>上海位于中国东部弧形海岸线的正中间,长江三角洲最东部,东临东海,南濒杭州湾,西与江苏、浙江两省相接 ...</p>
  115. <h2>环境</h2>
  116. <p>上海地处江南水乡,并位于长江入海口,亦不处于主要地震带上,因此如地震、洪水以及地质类灾害鲜有发生 ...</p>
  117. </div>
  118. </div>
  119. </div>
  120. <div class="footer">
  121. <p>请调整浏览器窗口的大小,以查看内容如何响应调整大小。</p>
  122. </div>
  123. </body>
  124. </html>

典型的设备断点

高度和宽度不同的屏幕和设备不计其数,因此很难为每个设备创建精确的断点。为了简单起见,您可以瞄准这五组:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  5. <style>
  6. .example {
  7. padding: 20px;
  8. color: white;
  9. }
  10. /* 超小型设备(600px及以下的手机) */
  11. @media only screen and (max-width: 600px) {
  12. .example {background: red;}
  13. }
  14. /* 小型设备(平板电脑竖屏模式和大屏手机,600 像素及以上) */
  15. @media only screen and (min-width: 600px) {
  16. .example {background: green;}
  17. }
  18. /* 中型设备(平板电脑横屏模式,768 像素及以上) */
  19. @media only screen and (min-width: 768px) {
  20. .example {background: blue;}
  21. }
  22. /* 大型设备(笔电、台式机,992 像素及以上) */
  23. @media only screen and (min-width: 992px) {
  24. .example {background: orange;}
  25. }
  26. /* 超大型设备(大屏笔电、台式机,1200 像素及以上) */
  27. @media only screen and (min-width: 1200px) {
  28. .example {background: pink;}
  29. }
  30. </style>
  31. </head>
  32. <body>
  33. <h1>典型的媒体查询断点</h1>
  34. <p class="example">请调整浏览器窗口的大小,来查看该段落的背景色在不同屏幕尺寸下如何变化。</p>
  35. </body>
  36. </html>

方向:人像 / 风景

媒体查询还可用于根据浏览器的方向来更改页面的布局。

您可以设置一组 CSS 属性,这些属性仅在浏览器窗口的宽度大于其高度时才适用,即所谓的“横屏”方向:

实例

如果方向为横向模式(landscape mode),则网页背景为浅蓝色:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  5. <style>
  6. body {
  7. background-color: lightgreen;
  8. }
  9. @media only screen and (orientation: landscape) {
  10. body {
  11. background-color: lightblue;
  12. }
  13. }
  14. </style>
  15. </head>
  16. <body>
  17. <p>请调整浏览器窗口的大小。如果此文档的宽度大于高度,背景色为“浅蓝色”,否则为“浅绿色”。</p>
  18. </body>
  19. </html>

用媒体查询隐藏元素

媒体查询的另一种常见用法是在不同屏幕尺寸上对元素进行隐藏:

在小屏幕上我会隐藏。
实例
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta name="viewport" content="width=device-width, initial-scale=1">
  5. <style>
  6. div.example {
  7. background-color: yellow;
  8. padding: 20px;
  9. }
  10. @media screen and (max-width: 600px) {
  11. div.example {
  12. display: none;
  13. }
  14. }
  15. </style>
  16. </head>
  17. <body>
  18. <h1>隐藏不同屏幕尺寸的元素</h1>
  19. <div class="example">Example DIV.</div>
  20. <p>当浏览器的宽度为 600 像素或更小时,隐藏 div 元素。请调整浏览器窗口的大小以查看效果。</p>
  21. </body>
  22. </html>

用媒体查询修改字体

您还可以使用媒体查询来更改不同屏幕尺寸上的元素的字体大小:

可变的字体大小。

实例
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta name="viewport" content="width=device-width, initial-scale=1">
  5. <style>
  6. div.example {
  7. background-color: lightgrey;
  8. padding: 20px;
  9. }
  10. @media screen and (min-width: 600px) {
  11. div.example {
  12. font-size: 80px;
  13. }
  14. }
  15. @media screen and (max-width: 600px) {
  16. div.example {
  17. font-size: 30px;
  18. }
  19. }
  20. </style>
  21. </head>
  22. <body>
  23. <h1>在不同的屏幕尺寸上更改元素的字体大小</h1>
  24. <div class="example">Example DIV.</div>
  25. <p>当浏览器的宽度为 600 像素或更小时,将 DIV 的字体大小设置为 30px。当它是 601 像素或更宽时,将字体大小设置为 80 像素。请调整浏览器窗口的大小以查看效果。</p>
  26. </body>
  27. </html>

CSS @media 参考手册

有关所有媒体类型和特性/表达式的完整概述,请在 CSS 参考手册中参阅 @media 规则

分类导航