实现媒体查询

课后整理 2021-3-2

可以使用两种方式针对特定的媒体类型定位CSS。此外,还有第三种方式,即使用@import 规则,不过一般不建议使用这种方法,因为它会影响性能。

第一种方式是使用link 元素的media属性,位于head 内。例如:

<head>
<link rel="stylesheet" href="your-styles.css" media="screen" />
</head>

第二种方式是在样式表中使用@media 规则。

/* 只用于打印的样式 */
@media print {
    header[role="banner"] nav, .ad {
        display: none;
    }
}

通过@media print 规则可以创建专门为打印浏览器里的页面定义的样式。也可以将它们与为其他媒体定义的样式放在一起。

媒体查询增强了媒体类型方法,允许根据特定的设备特性定位样式。要调整网站的呈现样式,让其适应不同的屏幕尺寸,采用媒体查询特别方便。

CSS3使用@media规则定义媒体查询,简化语法格式如下:

@media [only | not]? <media_type> [and <expression>]* | <expression> [and <expression>]*{
    /* CSS样式列表 */
}

参数简单说明如下:

媒体特性包括13种,接受单个的逻辑表达式作为值,或者没有值。大部分特性接受min或max的前缀,用来表示大于等于,或者小于等于的逻辑,以此避免使用大于号(>)和小于号(<)字符。下面列出了可以包含在媒体查询里的媒体特性。

还有一些非标准的媒体特性:

除了orientation、scan 和grid 以外,上述属性均可添加min-和max-前缀。min-前缀定位的是“大于等于”对应值的目标,而max- 前缀定位的则是“小于等于”对应值的目标。 CSS3 媒体查询规范中列出了关于所有媒体特性的描述(www.w3.org/TR/css3-mediaqueries/#media1)。

以下是媒体查询的基本语法。

下面代码定义了如果页面通过屏幕呈现,且屏幕宽度不超过480px,则加载shetland.css样式表。

<link rel="stylesheet" type="text/css" media="screen and (max-device-width: 480px)" href="shetland.css" />
@media logic type and (feature: value) {
    /* 目标CSS样式规则写在这里 */
}

对于响应式页面,大多数情况下我们需要将媒体查询放到样式表中。

/* 常规样式写在这里。
每个设备都能获取它们,除非被媒体查询中的样式规则覆盖 */
body { font: 200%/1.3 sans-serif;}
p {color: green;}
/* 以下针对不同的设备进行定制 */
@media (max-width : 600px) {
    /*匹配界面宽度小于等于600px的设备*/
}
@media (min-width : 400px) {
    /*匹配界面宽度大于等于400px的设备*/
}
@media (max-device-width : 800px) {
    /*匹配设备(不是界面)宽度小于等于800px的设备*/
}
@media (min-device-width : 600px) {
    /*匹配设备(不是界面)宽度大于等于600px的设备*/
}

本示例设计的媒体查询样式如下:

/* 480-767-only */
@media only screen and (min-width: 30em) and (max-width: 47.9375em) {
    /* 边栏 */  
    .about { overflow: hidden; }
    .about img {
        float: left;
        margin-right: 15px;
    }
}
/* 600-767-only */
@media only screen and (min-width: 37.5em) and (max-width: 47.9375em) {
    /* 边栏 */
    .about { padding-bottom: 1.4em; }
}
/* 768+ */
@media only screen and (min-width: 48em) {
    h1 { font-size: 2.25em; }
    /* 报头 */
    .masthead { padding-top: 10px; }
    .nav-main { margin-bottom: 0; }
    /* 主要内容 */
    .container {
        background: url(img/bg.png) repeat-y 65.938% 0;
        padding-bottom: 1.9375em;
    }
    main {
        float: left;
        width: 62.5%;
    }
    main > .post:first-child > h1 { margin-top: 0.904em; }
    .post-blurb p {
        font-size: 1em;
        line-height: 1.4;
    }
    .post-footer {
        padding-bottom: .7em;
        padding-top: .7em;
    }
    .footer p { font-size: 0.688em; }
    .pagination { margin-top: 45px; }
    /* 边栏 */
    .sidebar {
        float: right;
        margin-top: 1.875em;
        width: 31.25%;
    }
    .about p { font-size: 0.813em; }
    /* 页脚 */
    footer[role="contentinfo"] { border-top: 1px solid #cacbcb; }
}
/* --- 结束媒体查询 ---- */

最后,还需要在头部区域设置视口,即视觉区域。

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

这段代码的重点是width=device-width。有了这条语句,视觉区域的宽度会被设成与设备宽度(对iPhone 来说为320 像素)相同的值,因此在纵向模式下该宽度的页面内容会填充整个屏幕。如果不包含这一语句,使用媒体查询的min-width 和maxwidth特性将不会得到预期的结果。

代码中的initial-scale=1部分对width 和device-width 值没有影响,但通常会包含这一语句。它将页面的默认缩放级别设成了100%,换成纵向模式也一样。如果不设置initial-scale=1,在iPhone 中,手机从纵向模式改为横向模式时,网页会被放大,从而让布局与纵向模式的一致。

【提示】

视觉区域(viewport)指的是浏览器(包括桌面浏览器和移动浏览器)显示页面的区域。它不包含浏览器地址栏、按钮这样的东西,只是浏览区域。

媒体查询的width 特性对应的是视觉区域的宽度。不过,device-width 特性不是,它指的是屏幕的宽度。在移动设备(如iPhone)上,默认情况下这两个值通常不一样。Mobile Safari(iPhone 的浏览器)的视觉区域默认为980 像素宽,但iPhone 的屏幕只有320 像素宽(iPhone 的Retina 显示屏的屏幕分辨率有640 像素宽,但它们是在相同的空间挤入两倍的像素,因此设备宽度仍为320 像素)。

因此,iPhone 会像设为980 像素宽的桌面浏览器那样显示页面,并将页面缩小以适应320 像素的屏幕宽度(在纵向模式下)。结果,当在Mobile Safari 中浏览大部分为桌面浏览器建立的网站时,会显示将这些网站缩小了的样子。在横向模式下也是这样处理的,只不过宽度为480 像素(iPhone5 是568 像素)。如果不进行放大,页面通常是难以阅读的(注意不同设备的默认视觉区域宽度并不相同)。