利用媒体查询实现响应式布局
- 响应式布局原理
- 媒体查询应用
- 响应式布局示例
- 外部样式的引入方式
一、响应式布局原理
1.1响应式布局特点:网页宽度自动调整、尽量少使用绝对宽度、字体的大小使用相对单位(rem、em)、布局尽量使用浮动(流式布局)。
1.2响应式布局核心技术:媒体查询(@media)。
@media是css的@规则语句:@ + 标识符
关于css的@规则可以参考:https://developer.mozilla.org/zh-CN/docs/Web/CSS/At-rule
更严谨的说@media是嵌套@规则,如果满足@media的媒介查询条件,则条件规则组里面的规则生效。通俗的解释就是当显示器的条件满足@media的某一个样式,就是用该条件下的css样式。
@media查询条件分为两种,一种是媒体类型,一种是媒体特性。(详细可以参考:http://css.doyoe.com/ --> 语法与规则 --> @media)
1 /* 媒体查询语法 */ 2 @media 媒体类型 { 3 /* css样式 */ 4 } 5 @media 媒体特性 { 6 /* css样式 */ 7 } 8 @media 媒体类型 and 媒体特性 { 9 /* css样式 */ 10 } 11 @import url('xxx.css') 媒体特性;
1.3媒体类型:
all | 所有设备。 |
打印设备。 | |
screen | 彩色的电脑屏幕。 |
speech | 听觉设备,应用于屏幕阅读器等发声设备。 |
1.4媒体特性(这部分内容比较多,这里列举一些响应式布局可能用到的特性,详细内容可以参考:https://www.runoob.com/cssref/css3-pr-mediaquery.html):
更详细的媒体查询解析文档可以看这个:https://drafts.csswg.org/mediaqueries/
width | 宽度:页面的可见宽度。 |
height | 高度:页面的可见高度。 |
min-width、max-width | 最小宽度、最大宽度:页面的可见最小或最大宽度。 |
min-height、max-height | 最小高度、最大高度:页面的可见最小或最大高度。 |
orientation | 方向:页面可见区域高度是否大于或等于宽度。取值:landscape宽度大于高度(横屏);portrait高度大于宽度(竖屏)。 |
aspect-ratio | 宽高比 |
-webkit-device-pixel-ratio | 像素比(webkit内核私有的属性) |
1.5逻辑运算符:
and | 合并多个媒体类型(并且的意思) |
, | 酦醅某个媒体查询(或者的意思) |
not | 对媒体查询结果取反,不能单独使用(比如不能单独取all的反),也就是说对整体媒体查询结果取反。 |
only | 仅在媒体查询匹配成功后应用样式(防范老旧浏览器),这逻辑运算符主要用于解决老旧浏览器不能解析@media而直接将媒体查询作为普通样式直接作用。 |
示例1:
1 /* 所有设备、宽度必须大于700、横屏,这个三个条件同时满足才为true */ 2 @media all and (min-width:700px) and (orientation:landscape){ 3 /* 注意这里我遇到了选择器权重的问题,所以在媒体查询样式选择器添加了一个media类 */ 4 div.media{ 5 background-color: yellow; 6 } 7 } 8 div{ 9 width: 200px; 10 height: 200px; 11 background-color: red; 12 }
示例2:
/* 所有设备、宽度必须大于800或者竖屏的时候,true */ @media all and (min-width:800px),(orientation:portrait){ div.media{ background-color: yellow; } }
示例3:
//对示例2的整个媒体查询取反 @media not all and (min-width:800px),(orientation:portrait){ div.media{ background-color: yellow; } }
最后强调一下,@media是css3的功能,在来旧浏览器中会直接将媒体查询内的样式直接解析出来,为了防止这种情况,可以使用only解决,虽然现在的浏览器普片都能使用css3的语法了,但如果需要非常严谨的处理一些样式的话,还是需要用到only。
二、媒体查询应用
//html <div class="media"></div> //css div{ padding: 50px 0; border: 1px solid #000000; } div::after{ content: "这是一个房子"; } @media all and (max-width:1000px){ div.media{ background-color: #1177bb; } div.media::after{ content: "哇,好大的房子"; } } @media all and (max-width:800px){ div.media::after{ background-color: #aeaeae; } div.media::after{ content: "喔,房子变小了"; } } @media all and (max-width:500px){ div.media{ background-color: #46ae46; } div.media::after{ content: "哎,房子更小了"; } }
三、响应式布局示例
1.github链接(含图片):https://github.com/SnowElves/mediaLayout
2.代码:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <title></title> 7 <meta name="description" content=""> 8 <meta name="viewport" content="width=device-width, initial-scale=1"> 9 <link rel="stylesheet" href="index.css"> 10 </head> 11 <body> 12 <div class="overall"> 13 <!-- 头部 --> 14 <ul class="headNav media"> 15 <li class="logo"><a href="https://baidu.com" target="_blank"></a></li> 16 <li class="search"> 17 <input type="text" placeholder="请输入搜索内容"> 18 </li> 19 <li class="title"> 20 <a href="#">HTML</a> 21 <a href="#">CSS</a> 22 <a href="#">JavaScript</a> 23 <a href="#">ES6</a> 24 <a href="#">Node</a> 25 </li> 26 <li class="userInfo"> 27 <div class="imgUser"> 28 <img src="./image/user.png" alt=""> 29 </div> 30 <div class="text">他乡踏雪</div> 31 <div class="imgList"> 32 <img src="./image/userList.png" alt=""> 33 </div> 34 </li> 35 <li class="leftNavIocn"><img src="./image/leftNavIocn.png" alt=""></li> 36 </ul> 37 </div> 38 </body> 39 </html>
1 body, h1, h2, h3, h4, h5, h6, hr, p, blockquote, dl, dt, dd, ul, ol, li, pre, form, fieldset, legend, button, input, textarea, th, td { margin:0; padding:0; } 2 body, button, input, select, textarea { font:12px/1.5tahoma, arial, \5b8b\4f53; } 3 h1, h2, h3, h4, h5, h6{ font-size:100%; } 4 address, cite, dfn, em, var { font-style:normal; } 5 code, kbd, pre, samp { font-family:couriernew, courier, monospace; } 6 small{ font-size:12px; } 7 ul, ol { list-style:none; } 8 a { text-decoration:none; } 9 a:hover { text-decoration:underline; } 10 sup { vertical-align:text-top; } 11 sub{ vertical-align:text-bottom; } 12 legend { color:#000; } 13 fieldset, img { border:0; } 14 button, input, select, textarea { font-size:100%; } 15 table { border-collapse:collapse; border-spacing:0; } 16 17 @media all and (max-width:850px){ 18 19 .headNav.media{ 20 padding: 10px 10px; 21 justify-content:space-between; 22 } 23 .headNav.media li.search{ 24 flex: 1 1 auto; 25 margin-right: 30px; 26 } 27 .headNav.media li.title,li.leftNavIocn{ 28 display: none; 29 } 30 .headNav.media li.userInfo{ 31 justify-content:flex-end; 32 } 33 .headNav.media li.userInfo .text,.imgList{ 34 display: none; 35 } 36 37 } 38 @media all and (max-width:450px){ 39 .headNav.media{ 40 padding: 10px 10px; 41 } 42 .headNav.media li.logo,li.title,li.search{ 43 display: none; 44 } 45 46 .headNav.media li.userInfo{ 47 justify-content:flex-end; 48 } 49 .headNav.media li.userInfo .text,.imgList{ 50 display: none; 51 } 52 .headNav.media li.leftNavIocn{ 53 display: block; 54 } 55 56 } 57 58 59 60 .overall{ 61 position: relative; 62 } 63 /* 头部父级容器布局占用宽度60px */ 64 .headNav{ 65 padding: 10px 30px; 66 display: flex; 67 flex-direction: row; 68 background-color: #000000; 69 70 } 71 .headNav li{ 72 /* line-height: 30px; */ 73 } 74 /* logo占用宽度50px */ 75 .headNav .logo{ 76 flex: 0 0 28px; 77 margin-right: 20px; 78 height: 28px; 79 background-color: #ffffff; 80 border-radius: 15px; 81 overflow: hidden; 82 border: 1px solid #ffffff; 83 } 84 .headNav .logo a{ 85 display: block; 86 width: 28px; 87 height: 28px; 88 /* display: inline-block; 89 border-bottom: 30px solid #000000; 90 border-left: 15px solid #ffffff; 91 border-right: 15px solid #ffffff; */ 92 background-image: url("./image/github.jpg"); 93 background-size: 45px 30px; 94 background-repeat: no-repeat; 95 background-position: -8.5px -1.5px ; 96 } 97 /* 搜索栏占用宽度300px */ 98 .headNav .search{ 99 flex: 0 0 auto; 100 position: relative; 101 padding-left: 10px; 102 height: 30px; 103 border-radius: 15px; 104 background-color: rgb(59, 59, 59); 105 overflow: hidden; 106 } 107 108 .headNav .search::after{ 109 position: absolute; 110 top: 4px; 111 right: 10px; 112 display: block; 113 content: ""; 114 width: 14px; 115 height: 14px; 116 border: 1px solid #666666; 117 border-radius: 8px; 118 } 119 .headNav .search::before{ 120 position: absolute; 121 top: 17px; 122 right: 10px; 123 display: block; 124 content: ""; 125 height: 10px; 126 transform: rotate(-38deg); 127 border-left: 1px solid #666666; 128 } 129 .headNav .search:hover::after,.search:hover::before{ 130 border-color: #000000; 131 } 132 .headNav .search input{ 133 margin: 0; 134 width: 260px; 135 outline: none; 136 border:none; 137 line-height: 30px; 138 font-size: 14px; 139 color: #ffffff; 140 background-color:rgb(59, 59, 59) 141 } 142 /* 标题部分占用宽度500px */ 143 .headNav .title{ 144 flex: 1 0 270px; 145 padding-left: 30px; 146 /* width: 470px; */ 147 height: 30px; 148 overflow: hidden; 149 } 150 .headNav .title a{ 151 display: inline-block; 152 padding: 0 5px; 153 line-height: 30px; 154 } 155 /* */ 156 .headNav .userInfo{ 157 flex: 0 0 auto; 158 height: 30px; 159 color: #ffffff; 160 display: flex; 161 flex-direction:row; 162 flex-wrap:nowrap; 163 } 164 .headNav .userInfo div{ 165 padding-right: 10px; 166 } 167 .headNav .userInfo .imgUser{ 168 width: 20px; 169 padding-top: 5px; 170 } 171 .headNav .userInfo .imgUser img{ 172 width: 100%; 173 } 174 .headNav .userInfo .imgList{ 175 padding-top: 5px; 176 width: 20px; 177 } 178 .headNav .userInfo .imgList img{ 179 width: 100%; 180 } 181 .headNav .userInfo .text{ 182 line-height: 30px; 183 font-size: 14px; 184 } 185 /* */ 186 .headNav .leftNavIocn{ 187 flex: 0 0 20px; 188 /* width: 20px; */ 189 height: 23px; 190 padding-top: 7px; 191 } 192 .headNav .leftNavIocn img{ 193 width: 20px; 194 }
3.实现效果:
四、外部样式的引入方式
媒体查询的样式代码写在不同css文件中,然后再通过link标签引入,还可以通过在一个主CSS文件中使用@import来引入。
1.在link标签上引入:
<link rel="stylesheet" href="css/200.css" media="(max-width:200px)"></link> <link rel="stylesheet" href="css/500.css" media="(max-width:500px)"></link> <link rel="stylesheet" href="css/800.css" media="(max-width:800px)"></link>
2.@import引入:
但是@import存在一些问题,引入样式必须写在主样式文件的最上方,并且不能再html的上设定宽度,否则也不生效。
@import url("css/200.css") (max-width:200px);
@import url("css/500.css") (max-width:500px);
@import url("css/800.css") (max-width:800px);