1. 程式人生 > 實用技巧 >利用媒體查詢實現響應式佈局

利用媒體查詢實現響應式佈局

  • 響應式佈局原理
  • 媒體查詢應用
  • 響應式佈局示例

一、響應式佈局原理

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 所有裝置。
print 列印裝置。
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>
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 }
css程式碼

3.實現效果: