前端

媒体查询和响应式布局

2017-09-12  本文已影响0人  whitsats

CSS3 媒体查询与响应式布局

第一章 序论

现今每天都有更多的手机和平板电脑问市。消费者能够拥有可想象到的各种规格和形状的设备,但是网站开发人员却面临一个挑战:如何使他们的网站在传统浏览器、手机和平板电脑浏览器上有很好的效果,如何在各种大小的屏幕上提供一流的用户体验?
答案是:采用响应式设计。
响应式设计可以随所显示的屏幕大小而改变。实现响应式设计的主要方法是使用 CSS 媒体查询。
Bootstrap的栅格系统就是通过媒体查询来实现的。

第二章 回顾媒体类型 media type

HTML4 和 CSS2支持根据媒体类型(media type)加载。
比如,如果是'屏幕设备',则加载screen.css,如果是'打印设备',则加载print.css

HTML4和CSS2 支持媒体类型来决定使用CSS样式,例:

<link rel="stylesheet" type="text/css" media="screen" href="sans-serif.css">
<link rel="stylesheet" type="text/css" media="print" href="serif.css">

我们同样可以在CSS样式表中,声明条文适用于某些媒体类型。

@media screen {
  * { font-family: sans-serif }
}

可以在使用@import导入CSS时使用媒体查询,有条件地向当前样式表中加载其他样式表。

@import url("serif.css") screen;

printscreen媒体类型是HTML4中定义的.
HTML4定义的媒体类型如下:

令人尴尬的是,除了前3种类型,剩下的几乎没人用,实际已经废弃了.

第三章 媒体查询 media query

媒体查询是评估 True 或 False 的一种表达。如果为 True,则继续使用样式表。如果为 False,则不能使用样式表。这种简单逻辑通过表达式变得更加强大,使我们能够更灵活地对特定的设计场景使用自定义的显示规则。

媒体查询(media query)则根据媒体类型(medir type)和由媒体特征(media features)值组成的表达式.
媒体特征值如: width , height,color,即宽,高,色彩等.

共有13种特征(重点记住前3种) , 如下:

设 备 特 性 是否允许 min/max 前缀 特 性 的 值 说 明
width 允许 含单位的数值 指定浏览器窗口的宽度大小, 如480像素
height 允许 含单位的数值 指定浏览器窗口的高度大小, 如320像素
orientation 不允许 字符串值 指定移动设备浏览器的窗口方向。 只能指定portrait(纵向)和landscape (横向)两个值
device-width 允许 含单位的数值 指定移动设备的屏幕分 辨率宽度大小,如480像素
device-height 允许 含单位的数值 指定移动设备的屏幕分 辨率高度大小,如320像素
aspect-radio 允许 比例值 指定移动设备浏览器窗口的 纵横比例,如16:9
device-aspect-radio 允许 比例值 指定移动设备屏幕分辨率的 纵横比例,如16:9
color 允许 整数值 指定移动设备使用多少位的颜色值
color-index 允许 整数值 指定色彩表的色彩数
monochrome 允许 整数值 指定单色帧缓冲器中每像素的字节数
resolution 允许 分辨率值 指定移动设备屏幕的分辨率
scan 不允许 字符串值 指定电视机类型设备的扫描方式。 只能指定两种值:progressive表 示逐行扫描和interlace表示隔行扫描
grid 不允许 整数值 指定设备是基于栅格还是基于位图。 基于栅格时该值为1,否则为0

第四章 媒体查询实战

@media screen and (width: 600px){
    body {
        background: gray;
    }
}

上例指,对于屏幕且浏览器宽600px像素时,启用指定的css.
缩放浏览器试一下, 当浏览器窗口恰好是600px宽时,背景变灰.

上例中的媒体查询不是很实用,因为宽度恰好400px像素的条件太苛刻.
在实战中,用范围表达宽度更普遍.

@media screen and (min-width: 600px){
    body {
        background: gray;
    }
}

上例指:对于屏幕且最小600宽(>=600px)的浏览器时,启用指定的css.
拖动浏览器试一下?

同时,打印预览再看一下背景色,想一想为什么?

@media (orientation:portrait){
    body {
        background: gray;
    }
}

@media (orientation:landscape){
    body {
        background: blue;
    }
}

上例中,指屏幕height>width时,如手机竖直时,和屏幕width>height,如手机横放时,启动指定的css。

在针对所有设备的媒体查询中,可以使用简写语法,即省略关键字all(以及紧随其后的and)。换句话说,如果不指定关键字,则关键字就是all。

第五章 复杂表达式

媒体查询表达式还可以更复杂。

5.1 and联查

在表达式中,我们可以根据自己的喜好和需求使用任意数量的 and 条件。如果想要增加其他条件来检查特定的屏幕方向,只需添加另一个 and 关键词,后跟 orientation 媒体查询。

@media screen and (min-width:768px) and (max-width:1200px) and (orientation:landscape){
  *{
    background:blue;
  }
}

5.2 or条件

媒体查询中使用逗号分隔效果等同于 or 逻辑操作符。当使用逗号分隔的媒体查询时,如果任何一个媒体查询返回真,样式就是有效的。逗号分隔的列表中每个查询都是独立的,一个查询中的操作符并不影响其它的媒体查询。

@media (width:768px), screen and (orientation:portrait) {
    * {
        background: blue;
    }
}

5.3 not条件

not 关键字应用于整个媒体查询,在媒体查询为假时返回真,但仅能应用于整个查询,而不能单独应用于一个独立的查询。所有的not判断都在媒体查询的最后进行。

注意区分:

@media not all and (min-width:768px) {
  *{
    background:blue;
  }
}

等价于:

@media not (all and (min-width:768px)) {
  *{
    background:blue;
  }
}

虽然这么写也是错误的,我们只是用来理解not的判断顺序。

而不是:

@media (not all) and (min-width:768px){
  *{
    background:blue;
  }
}

第六章 响应式布局

6.1 思路

响应式布局即根据浏览器或屏幕的大小,调整页面的布局方式.

例:


response.jpg

先尝试做一些"不响应式"的div来,只考虑定义12个类,宽分别是1/12,2/12...12/12,且分别左浮.

*{
    box-sizing: border-box;
}

.col-xs-1,
.col-xs-2,
.col-xs-3,
.col-xs-4,
.col-xs-5,
.col-xs-6,
.col-xs-7,
.col-xs-8,
.col-xs-9,
.col-xs-10,
.col-xs-11,
.col-xs-12 {
    min-height:1px;
    float:left;
}


.col-xs-12 {
  width: 100%;
}
.col-xs-11 {
  width: 91.66666667%;
}
.col-xs-10 {
  width: 83.33333333%;
}
.col-xs-9 {
  width: 75%;
}
.col-xs-8 {
  width: 66.66666667%;
}
.col-xs-7 {
  width: 58.33333333%;
}
.col-xs-6 {
  width: 50%;
}
.col-xs-5 {
  width: 41.66666667%;
}
.col-xs-4 {
  width: 33.33333333%;
}
.col-xs-3 {
  width: 25%;
}
.col-xs-2 {
  width: 16.66666667%;
}
.col-xs-1 {
  width: 8.33333333%;
}
<div class="row">
    <div class="col-xs-3">第一列</div>
    <div class="col-xs-3">第二列</div>
    <div class="col-xs-3">第三列</div>
    <div class="col-xs-3">第四列</div>
</div>
<div class="row">
    <div class="col-xs-4">第五列</div>
    <div class="col-xs-4">第六列</div>
    <div class="col-xs-4">第七列</div>
</div>

无论我们怎么拖动浏览器的宽窄,这四列始终相对位置不变.

来一堆div

<div class="row">
    <div class="col-sm-4">三一列</div>
    <div class="col-sm-4">三二列</div>
    <div class="col-sm-4">三三列</div>
</div>

注意看类名col-sm-4,由于我们没有定义这个类,因此呈现div的默认效果,即宽100%,因此都是竖直方向堆积显示.

6.2 "响应式"布局

我们假设当浏览器变到768px宽时,col-sm-4变为25%宽,且左浮.
程序表达:

if(width>=768px) {
  .col-sm-4 {
    25%px;
    float:left;
  }
}

结合前面学的媒体查询Media Query,我们写如下代码:

@media (min-width: 768px) {
    .col-sm-1 {
    width: 8.333333%;
    }
    .col-sm-2 {
        width: 16.666667%;
    }
    .col-sm-3 {
        width: 25%;
    }

    .col-sm-4 {
        width: 33.333333%;
    }
    
    .col-sm-5 {
        width: 41.666667%;
    }

    .col-sm-6 {
        width: 50%;
    }

    .col-sm-7 {
        width: 58.333333%;
    }

    .col-sm-8 {
        width: 66.666667%;
    }

    .col-sm-9 {
        width: 75%;
    }

    .col-sm-10 {
      width: 83.333333%;
    }
    
    
    .col-sm-11 {
      width: 91.666667%;
    }
    
    .col-sm-12 {
      width: 100%;
    }

    .col-sm-1,
    .col-sm-2,
    .col-sm-3,
    .col-sm-4,
    .col-sm-5,
    .col-sm-6,
    .col-sm-7,
    .col-sm-8,
    .col-sm-9,
    .col-sm-10,
    .col-sm-11,
    .col-sm-12 {
        position: relative;
        float: left;
    }
 }

分析: 当浏览器width>=768px时,对应的css发挥作用,把col-sm-*的宽度按百分比设置,且左浮,形成了响应效果。

第七章 Bootstrap细节处的技巧

Container

有两个作用:

注意,不需要也不应该在 container 中嵌套另一个 container。

container.png

Row

Row 是 column 直接存在的容器,按照文档描述 row 中最多可有12个 column,不过可以通过套嵌的方式灵活扩展。同时作为都是左浮动的 column 的容器,自带清除浮动的性质。

同时 row 还有一个很特殊的地方,就是左右各有 -15px 的 margin,就是图片中的蓝色部分。这样也就抵消了上面提到的 container 中15px的 padding,那么为什么要这么折腾呢?接着看往下读。

注意:千万记住要把 row 放到 container 的内部,这样才能保证正常。

row.png

Column

注意,每个column 也会有15px的水平方向的 padding,也就是图片中黄色的部分,还记得上面提到的 row 的作用吗,column 只能在 row 中生存,由于 row 的 margin 为-15px,那么位于两边的 column 就碰到了 container 的边界。但是 colunmn 本身又有 15px 的 padding 使得它其中的内容并不会碰到 container,同时 不同column的内容之间就有了30px的槽。结合图片看一下就一目了然了。

注意:一定要把 column 放到 row 里使用。

column.png

Nesting

当把上面一系列的 container, row, column 都设置好,就可以通过套嵌 扩展它的栅格系统了,也就是在 column 中直接嵌套 row,而不需要再套一层 container:

nesting.png

还记得 container 和 column 都有15px的 padding 吗,对在套嵌的时候 column 的作用也相当于 container 了,这样就可以实现任意的嵌套了。

nesting2.png

1px

根据我们上面完善后的boolstrap,写一个最简单的布局:

<style type="text/css">
  .container{
      background:gray;
  }
</style>
<div class="container">
  <div class="row">
    <div class="col-sm-3"></div>
    <div class="col-sm-9">右面有九个</div>
  </div>
</div>

但是实际效果并不是我们想象的那样:

1px.jpg

左侧的3列并没有显示。

这是因为,我们的列都是左浮的,当左侧元素没有内容的时候,右侧的列会直接占据其位置。我们只需要给列一个最小的行高,即可解决这个问题。

.col-md-1,
.col-md-2,
.col-md-3,
.col-md-4,
.col-md-5,
.col-md-6,
.col-md-7,
.col-md-8,
.col-md-9,
.col-md-10,
.col-md-11,
.col-md-12{
  min-height:1px;
  padding:0px 15px;
}

列偏移

使用 .col-md-offset-*类可以将列向右侧偏移。这些类实际是通过使用选择器为当前元素增加了左侧的边距(margin)。
我们可以类似下面的方法实现列偏移:

.col-md-offset-4{
  margin-left:33.333%;
}

对于列排序,则是通过相对定位,重新定位列的位置。

Container和Container-fluid

通过分析源码,我们可以得知在Bootstrap中,container是阶梯状增长的,用于固定宽度并支持响应式布局的容器。

@media (min-width: 768px) {
  .container {
    width: 750px;
  }
}
@media (min-width: 992px) {
  .container {
    width: 970px;
  }
}
@media (min-width: 1200px) {
  .container {
    width: 1170px;
  }
}

而container-fluid则是用于 100% 宽度,占据全部视口(viewport)的容器。
我们设定container-fluid为

.container-fluid{
  width:100%;
  padding:0px 15px;
}

还有很多方法可以实现响应式布局 比如我们学过的弹性盒模型和display:table-cell

上一篇下一篇

猜你喜欢

热点阅读