CSS响应式全解

250 阅读4分钟

响应式布局

  • 2010年5月由Ethan Marcotte提出的一个概念
  • 一个网站兼容多种终端
  • 对不同尺寸的屏幕做出响应(媒体查询),并进行相应布局

媒体查询的语法

1.什么是媒体查询 (Media querys )

  • 一套样式很难适应各种大小的屏幕
  • 针对各种大小的屏幕写样式,让我们的页面在不同大小的屏幕上都能正常显示
/* 是屏幕设备并且屏幕宽度 >= 320px(断点 Breakpoint) */
@media screen and (min-width: 320px) {
    body {
        background-color: red;
    }
} 

2.媒体类型

  • all(所有设备 默认值)
  • screen(屏幕设备)
  • print(打印设备)
  • speech(屏幕阅读器,一般供残障人士使用)
/* all 和 screen 比较常用 */
@media screen and (min-width: 320px) {
    body {
        background-color: red;
    }
} 

@media all and (min-width: 320px) {
    body {
        background-color: red;
    }
}

/* all默认值可以去掉 */
@media (min-width: 320px) {
    body {
        background-color: red;
    }
}

3.媒体查询中的逻辑

  • 与( and )
  • 或( , )
  • 非( not )
/* 3.1.与( and ) */
/* 查询条件全部为真时生效 */

/* screen 并且屏幕宽度 >=320px 且 < 375px */
@media screen and (min-width: 320px) and (max-width: 375px) {
    body {
        background-color: red;
    }
}
/* 3.2.或( , ) */
/* 查询条件中的任意一个为真时生效 */

/* (screen 并且屏幕宽度 >= 375px) 或 (屏幕宽度 <= 320px) */
@media screen and (min-width: 375px), (max-width: 320px) {
    body {
        background-color: red;
    }
}

/*相当于 (screen 并且屏幕宽度 >=375px) 或 (all 并且屏幕宽度 <= 320px) */
@media screen and (min-width: 375px),all and (max-width: 320px) {
    body {
        background-color: red;
    }
} 
/* 3.3.非( not ) */
/* 对当前查询条件取反 */
/* 当 not 与 and 同时出现,not 对整个媒体查询生效 */

/* 取反(screen 并且屏幕宽度 >=320px 且 <= 375px) */
@media not screen and (min-width: 320px) and (max-width: 375px) {
    body {
        background-color: red;
    }
}

/* not 与逗号分隔的多个媒体查询同时存在时,not 只对它所在的那个查询生效 */
/* 取反(screen 并且屏幕宽度 >=375px) 或 (all 并且屏幕宽度 <= 320px) */
@media not screen and (min-width: 375px), all and (max-width: 320px) {
    body {
        background-color: red;
    }
}

4.媒体特性

width / max-width / min-width

-webkit-device-pixel-ratio / -webkit-max-device-pixel-ratio / -webkit-min-pixel-ratio

orientation: landscape / portrait

@media screen and (width: 320px) {
    body {
        background-color: red;
    }
} 

@media screen and (min-width: 320px) {
    body {
        background-color: red;
    }
} 

/* dpr <= 2 且屏幕水平方向 */
@media (-webkit-max-device-pixel-ratio: 2) and (orientation: landscape) {
    body {
        background-color: red;
    }
      }

断点和书写位置

  • 如何设置断点
  • 媒体查询的书写位置

1.如何设置断点 Breakpoint

* @media screen and (min-width: 320px) {
    body {
        background-color: red;
    }
} 
/* 1.1.经验总结 */
/*
    Bootstrap 的断点
    xs: < 576px 超小屏
    sm: 576px ~ 768px 小屏
    md: 768px ~ 992px 中屏
    lg: 992px ~ 1200px 大屏
    xl: >= 1200px 超大屏
*/

/* 1.2.改变屏幕大小,当页面显示不正常(或不符合要求)的时候,就需要设置断点了 */

2.媒体查询的书写位置

/* 2.1.样式表(style 标签或单独的 CSS 文件)中(推荐) */
<link rel="stylesheet" href="./css/index.css" /> 

/* 2.2.样式外链 link 中(不推荐) 会下载多份文件*/
<link
rel="stylesheet"
href="./css/mobile.css"
media="screen and (max-width: 768px)"
/>
<link
rel="stylesheet"
href="./css/pc.css"
media="screen and (min-width: 768px)"
/> 

媒体查询的策略

  • 无策略
  • PC端优先
  • 移动端优先
<style>
    /* css reset */
    * {
        box-sizing: border-box;
        padding: 0;
        margin: 0;
    }
    body {
        padding-top: 200px;
    }
    img {
        width: 100%;
    }
    .row {
        width: 100%;
        display: flex;
        flex-wrap: wrap;
    }
    .col {
        padding-top: 10px;
        padding-bottom: 10px;
        background-color: rgba(86, 61, 124, 0.15);
        border: 1px solid rgba(86, 61, 124, 0.2);
    }
</style>

<div class="row">
    <div class="col">
        <img src="images/1.png" alt="" />
    </div>
    <div class="col">
        <img src="images/1.png" alt="" />
    </div>
    <div class="col">
        <img src="images/1.png" alt="" />
    </div>
    <div class="col">
        <img src="images/1.png" alt="" />
    </div>
    <div class="col">
        <img src="images/1.png" alt="" />
    </div>
    <div class="col">
        <img src="images/1.png" alt="" />
    </div>
    <div class="col">
        <img src="images/1.png" alt="" />
    </div>
    <div class="col">
        <img src="images/1.png" alt="" />
    </div>
    <div class="col">
        <img src="images/1.png" alt="" />
    </div>
    <div class="col">
        <img src="images/1.png" alt="" />
    </div>
    <div class="col">
        <img src="images/1.png" alt="" />
    </div>
    <div class="col">
        <img src="images/1.png" alt="" />
    </div>
</div>

无策略

@media (max-width: 576px) {
    .col {
        width: 100%;
    }
}
@media (min-width: 576px) and (max-width: 768px) {
    .col {
        width: 50%;
    }
}
@media (min-width: 768px) and (max-width: 992px) {
    .col {
        width: 25%;
    }
}
@media (min-width: 992px) and (max-width: 1200px) {
    .col {
        width: 16.666667%;
    }
}
@media (min-width: 1200px) {
    .col {
        width: 8.333333%;
    }
}

PC端优先

/* PC first PC 端优先 */
/* 从大到小 */
.col {
    width: 8.333333%;
}
@media (max-width: 1200px) {
    .col {
        width: 16.666667%;
    }
}
@media (max-width: 992px) {
    .col {
        width: 25%;
    }
}
@media (max-width: 768px) {
    .col {
        width: 50%;
    }
}
@media (max-width: 576px) {
    .col {
        width: 100%;
    }
} 

移动端优先

/* mobile first 移动端优先(推荐) */
/* 从小到大 */
.col {
    width: 100%;
}
@media (min-width: 576px) {
    .col {
        width: 50%;
    }
}
@media (min-width: 768px) {
    .col {
        width: 25%;
    }
}
@media (min-width: 992px) {
    .col {
        width: 16.666667%;
    }
}
@media (min-width: 1200px) {
    .col {
        width: 8.333333%;
    }
}

移动端常用单位

// px
// 绝对单位
// 当需要设置固定宽高时可用,也可用于设置字体大小

// % 可以用来布局
// 相对单位
// 一般用来设置宽度,相对于父元素,流体布局中会用到
// 如果是绝对定位,该元素百分比参照最近有定位属性祖先元素,固定定位则是视口

// em
// 相对单位
// 设置字体大小时,1em=父元素字体的大小
// 设置其他,比如宽、高时,1em=自身字体的大小
// 一般用来控制行首的缩进,一般不用来布局

// rem(root element html)  可以用来布局
// 相对单位
// 1rem=根元素(html)的字体大小

// vw/vh/vmax/vmin  可以用来布局
// 相对单位,视口单位
// 1vw=视口宽度的 1%
// 1vh=视口高度的 1%
// vmin:当前 vw 和 vh 中较小的一个值
// vmax:当前 vw 和 vh 中较大的一个值

响应式rem

html {
    font-size: 4px;
}
@media (min-width: 320px) {
    html {
        font-size: 5px;
    }
}
@media (min-width: 414px) {
    html {
        font-size: 6px;
    }
}
@media (min-width: 540px) {
    html {
        font-size: 8px;
    }
}
@media (min-width: 768px) {
    html {
        font-size: 11px;
    }
}
@media (min-width: 992px) {
    html {
        font-size: 14px;
    }
}
@media (min-width: 1200px) {
    html {
        font-size: 18px;
    }
}

JS rem

{
    const docEl = document.documentElement;

    const setHtmlFontSize = () => {
        const viewWidth = docEl.clientWidth;
        // 1rem = 10px
        docEl.style.fontSize = `${viewWidth / 75}px`;
    };

    setHtmlFontSize();
    window.addEventListener('resize', setHtmlFontSize, false);
}

min-width和max-width

min-width是用来限制元素的最小宽度,max-width用来限制元素的最大宽度

当元素的width大于max-width width失效 当元素width小于min-width width失效

1、min-width,max-width的权重高

如果当元素设置了min-width,max-width,即使在width后面使用!important,如果元素实际width没在 其 min 和 max 范围之内 也不会显示width的值

.box {
  /* width 小于 min-width   失效 */
  width:200px;
  min-width:300px;
  height:300px;
  background-color:red;
}
.box {
    /* width 大于 max-width   失效 */
    width:800px;
    max-width:600px;
    height:600px;
    background-color:red;
}

2、min-width与max-width值的大小出现冲突

当 min-width 和 max-width 同时存在, 谁大显示谁

.box {
  min-width:600px;
  max-width:900px;
  height:600px;
  background-color:red;
}
.box {
  min-width:600px;
  max-width:900px;
  height:600px;
  background-color:red;
}

3、利用max-heigth可以实现意高度元素的展开收起动画技术

min-height和max-heigth也同样类似, 在不知道元素具体区域宽高的时候,使用这些属性能很好让网站实现自适应效果。

.element {
 max-height: 0;
 overflow: hidden;
 transition: max-height .25s;
}
.element.active {
 max-height: 666px; /* 一个足够大的最大高度值,保证比展开内容高度大 */
}