## 一、百分比適配
### 1、要點
- 元素的寬度使用了百分比來定寬,根據屏幕的寬度進行自適應
- 適合頁面內容結構均勻分配,固定高度,結構不是很復雜,注意要設置viewport視口內容寬度等于設備的寬度
- 使用百分比定寬的元素,百分比參考的是該元素最近的,定了寬度的父元素
### 2、示例
```
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no">
<title>固定高度,寬度自適應,100%比做適配</title>
<style type="text/css">
*{
padding:0;
margin:0;
}
body{
font-size:16px;
overflow:hidden;
-webkit-box-sizing:border-box;
box-sizing:border-box;
}
/*left start*/
.left{
width:40px; /*兩邊固定寬度,中間自適應*/
height:40px; /*高度可以不加,由內容填充*/
position:absolute;
left:0;
top:0;
background:red;
text-align:center;
line-height:40px;
}
/*left end*/
/*center start*/
.center{
width:100%; /*寬度不固定*/
background:orange;
height:40px;
margin-left:40px;
}
.center input{
width:100%;
height:40px;
outline:none;
}
/*center end*/
/*right start*/
.right{
width:40px; /*兩邊固定寬度,中間自適應*/
height:40px; /*高度可以不可,由內容填充*/
text-align:center;
line-height:40px;
position:absolute;
right:0;
top:0;
background:green;
}
/*right end*/
/*banner adv start*/
.banner{
width:100%;
height:200px;
background:pink;
text-align:center;
line-height:200px;
}
/*banner adv end*/
/*list start*/
.list{
overflow:hidden;
}
.list div{
width:20%;
height:90px;
float:left;
text-align:center;
line-height:90px;
}
.list div:nth-of-type(1){
background:orange;
}
.list div:nth-of-type(2){
background:#80B3FF;
}
.list div:nth-of-type(3){
background:#1BA260;
}
.list div:nth-of-type(4){
background:#F2A196;
}
.list div:nth-of-type(5){
background:#FFCE42;
}
.listTwo{
margin:15px 0 0 0;
}
/*list end*/
/*con start*/
.con{
width:100%;
height:200px;
overflow:hidden; /*子元素使用來浮動,父元素記得清除浮動*/
text-align:center;
line-height:200px;
}
.left-80{
width:80%;
height:100%; /*想要一個元素在頁面中顯示必須得給元素高度,繼承父元素*/
float:left;
background:#B0E24A;
}
.right-20{
width:20%;
height:100%; /*高度100%,繼承父元素的高度*/
float:right;
background:#6C6863;
}
/*con end*/
</style>
</head>
<body>
<!-- header start -->
<header>
<div class="left">左邊</div>
<div class="center">
<form>
<input type="search" name="">
</form>
</div>
<div class="right">右邊</div>
</header>
<!-- header end -->
<!-- banner adv start -->
<div class="banner">adv</div>
<!-- banner adv end -->
<!-- 列表list start -->
<div class="list">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
</div>
<div class="list listTwo">
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
<div>10</div>
</div>
<!-- 列表list end -->
<!-- con內容開始-->
<div class="con">
<div class="left-80">左邊80%</div>
<div class="right-20">右邊20%</div>
</div>
<!-- con內容結束-->
</body>
</html>
```
## 二、@media 媒體查詢適配
### 1、CSS 語法
#### (1)@media 媒體類型 and (媒體特性){ 你的樣式 }
```
@media mediatype and|not|only (media feature) {
CSS-Code;
}
```
#### (2)針對不同的媒體使用不同 stylesheets
```
<link rel="stylesheet" media="mediatype and|not|only (media feature)" href="mystylesheet.css">
```
### 2、媒體查詢功能
#### (1)最大寬度max-width
“max-width”是媒體特性中最常用的一個特性,其意思是指媒體類型小于或等于指定的寬度時,樣式生效。如:
```
@media screen and (max-width:480px){
.ads {
display:none;
}
}
```
上面表示的是:當屏幕小于或等于480px時,頁面中的廣告區塊(.ads)都將被隱藏。
#### (2)最小寬度min-width
“min-width”與“max-width”相反,指的是媒體類型大于或等于指定寬度時,樣式生效。
```
@media screen and (min-width:900px){
.wrapper {width: 980px;}
}
```
上面表示的是:當屏幕大于或等于900px時,容器“.wrapper”的寬度為980px。
#### (3)多個媒體特性使用
Media Queries可以使用關鍵詞"and"將多個媒體特性結合在一起。也就是說,一個Media Query中可以包含0到多個表達式,表達式又可以包含0到多個關鍵字,以及一種媒體類型。
當屏幕在600px~900px之間時,body的背景色渲染為“#f5f5f5”,如下所示。
```
@media screen and (min-width:600px) and (max-width:900px){
body {background-color:#f5f5f5;}
}
```
#### (4)設備屏幕的輸出寬度Device Width
在智能設備上,例如iPhone、iPad等,還可以根據屏幕設備的尺寸來設置相應的樣式(或者調用相應的樣式文件)。同樣的,對于屏幕設備同樣可以使用“min/max”對應參數,如“min-device-width”或者“max-device-width”。
```
<link rel="stylesheet" media="screen and (max-device-width:480px)" href="iphone.css" />
```
上面的代碼指的是“iphone.css”樣式適用于最大設備寬度為480px,比如說iPhone上的顯示,這里的“max-device-width”所指的是設備的實際分辨率,也就是指可視面積分辨率。
#### (5)not關鍵詞
使用關鍵詞“not”是用來排除某種制定的媒體類型,也就是用來排除符合表達式的設備。換句話說,not關鍵詞表示對后面的表達式執行取反操作,如:
```
@media not print and (max-width: 1200px){樣式代碼}
```
上面代碼表示的是:樣式代碼將被使用在除打印設備和設備寬度小于1200px下所有設備中。
#### (6)only關鍵詞
only用來指定某種特定的媒體類型,可以用來排除不支持媒體查詢的瀏覽器。其實only很多時候是用來對那些不支持Media Query但卻支持Media Type的設備隱藏樣式表的。
其主要有:支持媒體特性的設備,正常調用樣式,此時就當only不存在;表示不支持媒體特性但又支持媒體類型的設備,這樣就會不讀樣式,因為其先會讀取only而不是screen;另外不支持Media Queries的瀏覽器,不論是否支持only,樣式都不會被采用。如
```
<link rel="stylesheet" media="only screen and (max-device-width:240px)" href="android240.css" />
```
在Media Query中如果沒有明確指定Media Type,那么其默認為all,如:
```
<link rel="stylesheet" media="(min-width:701px) and (max-width:900px)" href="mediu.css" />
```
另外在樣式中,還可以使用多條語句來將同一個樣式應用于不同的媒體類型和媒體特性中,指定方式如下所示。
```
<link rel="stylesheet" type="text/css" href="style.css" media="handheld and (max-width:480px), screen and (min-width:960px)" />
```
### 3、移動端適配用法
```
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" />
/*iphone4*/
@media only screen and (min-width: 320px) and (max-width: 480px) {
html, body {
font-size: 12px;
}
.title {
background-color: red;
}
}
/*iphone5*/
@media only screen and (min-width: 320px) and (max-width: 568px) {
html,body {
font-size: 14px;
}
.title {
background-color: blue;
}
}
/*ihpne6,7,8*/
@media only screen and (min-width: 375px) and (max-width: 413px) {
html,body {
font-size: 16px;
}
.title {
background-color: green;
}
}
/*ihpne6,7,8Plus*/
@media only screen and (min-width: 414px) and (max-width: 640px) {
html,body {
font-size: 18px;
}
.title {
background-color: pink;
}
}
```
## 三、Flex布局適配
- 適合頁面內容結構均勻分配,固定高度,需要設置viewport視口內容寬度等于設備寬度
- 老版本的display:box與新版本的display:flex都可以實現頁面的自適應
### 1、新老版本語法對比


### 2、示例
```
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no">
<title>Flex布局適配</title>
<style type="text/css">
*{
padding:0;
margin:0;
}
body{
font-family:"微軟雅黑";
font-size:16px;
}
.parent{
display:-webkit-flex; /*聲明彈性盒模型*/
display:flex;
}
.left,.right{
width:40px;
height:40px;
text-align:center;
line-height:40px;
}
.left{
background:#abcdef;
}
.right{
background:#DD4F43;
}
.center{
-webkit-flex:1; /*一定要注意加上瀏覽器前綴,否則就會失效*/
flex:1;
}
.center input{
width:100%;
height:40px;
outline:none;
}
.banner-adv{
width:100%;
height:200px;
display:-webkit-box;
display:box;
background:#0D6CB0;
}
.list{
width:100%;
height:90px;
display:-webkit-flex;
display:flex;
}
.list div{
-webkit-flex:1;
flex:1;
text-align:center;
line-height:90px;
}
.list div:nth-of-type(1){
background:#DE5246;
}
.list div:nth-of-type(2){
background:#19A25F;
}
.list div:nth-of-type(3){
background:#FF8080;
}
.list div:nth-of-type(4){
background:#F4CD0B;
}
.list div:nth-of-type(5){
background:#9EDA45;
}
.list-Two{
margin:15px 0 0 0;
}
.list-Two div:nth-of-type(1){
background:#B847FF;
}
.list-Two div:nth-of-type(2){
background:#79B900;
}
.list-Two div:nth-of-type(3){
background:#FF2424;
}
.list-Two div:nth-of-type(4){
background:#D2E4F0;
}
.list-Two div:nth-of-type(5){
background:#4CDF2B;
}
.con{
height:200px;
display:-webkit-flex; /*聲明彈性盒模型*/
display:flex;
}
.con div:nth-of-type(1){
-webkit-flex:8; /*根據父元素分成8等分,占80%*/
flex:8;
background:#80B3FF;
}
.con div:nth-of-type(2){
-webkit-flex:2; /*根據父元素分成2等分,占20%*/
flex:2;
background:#CD8B37;
}
</style>
</head>
<body>
<header class="parent">
<div class="left">左邊</div>
<div class="center">
<form>
<input type="search" name="">
</form>
</div>
<div class="right">右邊</div>
</header>
<div class="banner-adv"></div>
<section class="list">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
</section>
<section class="list list-Two">
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
<div>9</div>
</section>
<div class="con">
<div></div>
<div></div>
</div>
</body>
</html>
```
## 四、動態 rem 方案
### 1、rem/em/vw/vh的比較
#### (1)em
**em作為font-size的單位時,其代表父元素的字體大小,em作為其他屬性單位時,代表自身字體大小——MDN**
比如父元素font-size:12px;
自身元素如果寫成:font-sise:2em;則自身元素用px表示就是24px(相對父元素字體大小);
但是自身元素設置:width:2em,那么自身元素用px表示就是48px(相對自身字體大小);
#### (2)rem
**rem作用于非根元素時,相對于根元素字體大小;rem作用于根元素字體大小時,相對于其出初始字體大小——MDN**
比如根元素(html)設置font-size=12px; 非根元素設置width:2rem;則換成px表示就是24px;
如果根元素設置成font-size=1rem;則根元素換成px就是相對于初始字體大小,一般是12px;
#### (3)vw/vh
**vw : 視口寬度的 1/100;vh :視口高度的 1/100 —— MDN**
在pc端,視口寬高就是瀏覽器得寬高;
在移動端,這個還不太一樣,不過一般設置:
```
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
```
代碼以顯示網頁的屏幕寬度定義了視窗寬度。網頁的比例和最大比例被設置為100%。
### 2、剖析rem布局原理
其實好好理解上面的概念,rem的原理也就很簡單了。
假設我們將**屏幕平局分為10份**,每一份寬度用一個a表示,即**a=屏幕寬度/10**,那么:
```
div {width: 5a} /* 屏幕寬度的50% */
```
但是css中沒有a這個單位,這時我們可以借助rem代替上面的a。如:
```
html {font-size: 12px}
div {width: 2rem} /* 24px*/
html {font-size: 16px}
div {width: 2rem} /* 32px*/
```
新的問題來?怎么讓html元素字體大小恒等于屏幕的1/10呢?如ipone6寬是375px,font-size:37.5px;
```
html {fons-size: width / 10}
div {width: 5rem} /* 5rem = 5a = 屏幕寬度的50% */
```
我們用js很容易動態的設置html的font-size恒等屏幕的1/10;我們可以在頁面dom ready、resize和屏幕旋轉中設置:
```
document.documentElement.style.fontSize = document.documentElement.clientWidth / 10 + 'px';
```
如何把設計稿的像素單位換成以rem為單位?可以用一個比例來計算:如設計稿寬度為750px,某個元素量得75px,那么:
75px/750px = 計算所得rem/10rem,所以計算所得rem=75px;所以我們在樣式中寫width:1rem;實際寬度是75px;同理,如果設計稿總寬度是640px,則1rem=64px。
預處理函數可以簡化:
```
$ue-width: 750; /* 設計稿圖的寬度 */
@function px2rem($px) {
@return #{$px/$ue-width*10}rem;
}
div {
width: px2rem(100);/*編譯后: p{width:1.5625rem}*/
}
```
### 3、rem布局方案
rem是一種彈性布局,它強調等比縮放,100%還原。它和響應式布局不一樣,響應式布局強調不同屏幕要有不同的顯示,比如媒體查詢。
最佳方案:**rem+flexbox+js的方案**
實現步驟:
- 引入相關flexible.js文件
- 根據設計圖計算元素rem值
- 切換不同移動端視窗查看效果
#### 示例1:網易考拉
地址:[https://m.kaola.com/](https://m.kaola.com/)
```
(function(win) {
var remCalc = {};
var docEl = win.document.documentElement,
tid;
function refreshRem() {
var width = docEl.getBoundingClientRect().width;
if (width > 640) {
width = 640
}
var rem = width / 10;
docEl.style.fontSize = rem + "px";
remCalc.rem = rem;
var actualSize = parseFloat(window.getComputedStyle(document.documentElement)["font-size"]);
if (actualSize !== rem && actualSize > 0 && Math.abs(actualSize - rem) > 1) {
var remScaled = rem * rem / actualSize;
docEl.style.fontSize = remScaled + "px"
}
}
function dbcRefresh() {
clearTimeout(tid);
tid = setTimeout(refreshRem, 100)
}
win.addEventListener("resize",
function() {
dbcRefresh()
},
false);
win.addEventListener("pageshow",
function(e) {
if (e.persisted) {
dbcRefresh()
}
},
false);
refreshRem();
remCalc.refreshRem = refreshRem;
remCalc.rem2px = function(d) {
var val = parseFloat(d) * this.rem;
if (typeof d === "string" && d.match(/rem$/)) {
val += "px"
}
return val
};
remCalc.px2rem = function(d) {
var val = parseFloat(d) / this.rem;
if (typeof d === "string" && d.match(/px$/)) {
val += "rem"
}
return val
};
win.remCalc = remCalc
})(window); (function(win, doc) {
var type = navigator.userAgent.match(/(iPhone|iPod|iPad)/i) ? "ios": "aos";
win.deviceType = type
})(window, document);
```
#### 示例2:
```
;(function (doc, win) {
var docEl = doc.documentElement,
resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
recalc = function () {
var clientWidth = docEl.clientWidth;
if (!clientWidth) return;
if (clientWidth >= 750) {
docEl.style.fontSize = '100px';
} else {
docEl.style.fontSize = 100 * (clientWidth / 750) + 'px';
}
};
if (!doc.addEventListener) return;
win.addEventListener(resizeEvt, recalc, false);
doc.addEventListener('DOMContentLoaded', recalc, false);
})(document, window);
```
## 五、 css實現單行、多行文本超出顯示省略號
### 1、單行文本省略
```
<p class="ellipsis-line">在使用的時候,有時候發現不會出現省略標記效果,經過測試發現,使用ellipsis的時候,必須配合overflow:hidden; white-space:nowrap; width:具體值;這三個樣式共同使用才會有效果。</p>
.ellipsis-line {
border: 1px solid #f70505;
padding: 8px;
width: 400px;
overflow: hidden;
text-overflow: ellipsis; /*文本溢出顯示省略號*/
white-space: nowrap; /*文本不會換行*/
}
```
**語法:text-overflow:clip/ellipsis;**
- 默認值:clip
- 適用于:所有元素
- clip: 當對象內文本溢出時不顯示省略標記(...),而是將溢出的部分裁切掉。
- ellipsis: 當對象內文本溢出時顯示省略標記(...)。
**注**:在使用的時候,有時候發現不會出現省略標記效果,經過測試發現,使用ellipsis的時候,必須配合overflow:hidden; white-space:nowrap; width:具體值;這三個樣式共同使用才會有效果。
### 2、多行文本省略
#### (1)直接用css屬性-webkit-line-clamp:n;設置
在WebKit瀏覽器或移動端(絕大部分是WebKit內核的瀏覽器)的頁面實現比較簡單,可以直接使用WebKit的CSS擴展屬性(WebKit是私有屬性)-webkit-line-clamp ;注意:這是一個 不規范的屬性(unsupported WebKit property),它沒有出現在 CSS 規范草案中。
-webkit-line-clamp用來限制在一個塊元素顯示的文本的行數。 為了實現該效果,它需要組合其他的WebKit屬性。常見結合屬性:
- display: -webkit-box; 必須結合的屬性 ,將對象作為彈性伸縮盒子模型顯示 。
- -webkit-box-orient 必須結合的屬性 ,設置或檢索伸縮盒對象的子元素的排列方式 。
- text-overflow: ellipsis;,可以用來多行文本的情況下,用省略號“…”隱藏超出范圍的文本。
這個屬性只合適WebKit瀏覽器或移動端(絕大部分是WebKit內核的)瀏覽器
```
<p class="multi-line">在WebKit瀏覽器或移動端(絕大部分是WebKit內核的瀏覽器)的頁面實現比較簡單,可以直接使用WebKit的CSS擴展屬性(WebKit是私有屬性)-webkit-line-clamp ;注意:這是一個 不規范的屬性(unsupported WebKit property),它沒有出現在 CSS 規范草案中。</p>
.multi-line {
border: 1px solid #f70505;
width: 400px;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
}
```
**效果優點:**
- 響應式截斷,根據不同寬度做出調整
- 文本超出范圍才顯示省略號,否則不顯示省略號
- 瀏覽器原生實現,所以省略號位置顯示剛好
但是缺點也是很直接,因為 -webkit-line-clamp 是一個不規范的屬性,它沒有出現在 CSS 規范草案中。也就是說只有 webkit 內核的瀏覽器才支持這個屬性,像 Firefox, IE 瀏覽器統統都不支持這個屬性,瀏覽器兼容性不好。
**使用場景**:多用于移動端頁面,因為移動設備瀏覽器更多是基于 webkit 內核,除了兼容性不好,實現截斷的效果不錯。
#### (2)利用定位和偽類元素
```
p {
position: relative;
width:400px;
line-height: 20px;
max-height: 60px;
overflow: hidden;
}
p::after {
content: "...";
position: absolute;
bottom: 0;
right: 0;
padding-left: 40px;
background: -webkit-linear-gradient(left, transparent, #fff 55%);
background: -o-linear-gradient(right, transparent, #fff 55%);
background: -moz-linear-gradient(right, transparent, #fff 55%);
background: linear-gradient(to right, transparent, #fff 55%);
}
```
適合場景:文字內容較多,確定文字內容一定會超過容器的,那么選擇這種方式不錯。但文字未超出行的情況下也會出現省略號,可結合js優化該方法。
注:
- 將height設置為line-height的整數倍,防止超出的文字露出。
- 給p::after添加漸變背景可避免文字只顯示一半。
- 由于ie6-7不顯示content內容,所以要添加標簽兼容ie6-7(如:<span>…<span/>);兼容ie8需要將::after替換成:after。
#### (3)結合js優化代碼
**css:**
```
p {
position: relative;
width: 400px;
line-height: 20px;
overflow: hidden;
}
.p-after:after {
content: "...";
position: absolute;
bottom: 0;
right: 0;
padding-left: 40px;
background: -webkit-linear-gradient(left, transparent, #fff 55%);
background: -moz-linear-gradient(left, transparent, #fff 55%);
background: -o-linear-gradient(left, transparent, #fff 55%);
background: linear-gradient(to right, transparent, #fff 55%);
}
```
**js:**
```
<script src="https://cdn.bootcss.com/jquery/3.5.0/jquery.min.js"></script>
<script>
$(function(){
//獲取文本的行高,并獲取文本的高度,假設我們規定的行數是五行,那么對超過行數的部分進行限制高度,并加上省略號
$('p').each(function(i, obj){
var lineHeight = parseInt($(this).css("line-height"));
var height = parseInt($(this).height());
if((height / lineHeight) >3 ){
$(this).addClass("p-after")
$(this).css("height","60px");
}else{
$(this).removeClass("p-after");
}
});
})
</script>
```
- 前言
- 一、css垂直居中的幾種實現方法
- 二、簡單說一下盒模型,說下如何利用BFC解決外邊距重疊的問題
- 三、說一說產生塌陷的原因以及清除浮動的幾種方法
- 四、偽類和偽元素的區別?聊一下css選擇器的優先級
- 五、css中的過渡和動畫效果了解嗎
- 六、彈性盒模型了解嗎
- 七、簡單說下BOM和DOM的區別
- 八、如何解決瀏覽器的兼容性問題?瀏覽器調優都用到過哪些方法
- 九、之前寫過h5嗎?有遇到過哪些兼容性問題?說下怎么解決的
- 十、h5是如何做移動端適配的?折行的時候如何實現不斷行
- 十一、聊一聊js中實現數組拷貝的常用方法
- 十二、聊聊js中的數據類型,如何用js實現一個對象的深拷貝
- 十三、偽數組和數組的區別?相互轉化的方法有哪些
- 十四、請介紹Js中有哪些循環遍歷的方法,關于數組常用的方法有哪些
- 十五、js中的reduce了解嗎?都用他解決過什么問題
- 十六、事件冒泡和捕獲的執行順序了解嗎?什么是事件委托
- 十七、call和apply的區別是什么?caller和callee的區別有哪些
- 十八、javascript中的this都有哪些用法
- 十九、怎么理解js中的原型鏈?如何實現繼承?實現繼承常用的方式有哪些
- 二十、聊一聊js的作用域和作用域鏈
- 二十一、js的閉包了解嗎?閉包的常見用法說一下
- 二十二、setTimeout和setInterval的運行機制了解嗎
- 二十三、函數的柯里化了解嗎?說下函數柯里化應用的場景
- 二十四、用js寫一個ajax的原生實現方法
- 二十五、js如何實現跨域?聊一聊你之前用到過的方法
- 二十六、聊一下cookie、session和token三者的區別及使用
- 二十七、用js實現一下數組去重和排序,有哪些方法可以實現
- 二十八、寫一個方法,統計一下html文檔的元素包括元素的數量
- 二十九、用js實現一個省市級聯效果
- 三十、用js實現一個輪播圖效果,簡單說下原理
- 三十一、請你實現一個大文件上傳和斷點續傳
- 三十二、什么是模塊化開發?談下AMD、CMD、CommonJs和ES6的區別
- 三十三、es6了解嗎?說幾個常見的新特性,set和weakSet的區別是什么
- 三十四、解構賦值的用法了解嗎?如何實現對象和數組的嵌套和重命名
- 三十五、談談你對promise的用法和理解
- 三十六、談談你對es6中的Generator函數的認識
- 三十七、談一下async-await的實現原理
- 三十八、用js實現一下觀察者模式?簡單說一下原理
- 三十九、了解JavaScript中的裝飾器嗎?聊一下JS中的getter與setter的用法
- 四十、聊一下正則表達式里的常見用法