【建議收藏】css晦澀難懂的點都在這啦

前言

CSS你們確定都是會的可是每一個人所撐握的狀況都不同,特別是已經工做幾年的前輩(這裏指的是我司)不少CSS玩法都不知道,可能他們已經習慣了用組件, 可是面試的時候又不可避免問,因此我整理了下CSS比較晦澀難懂的點總結寫了這篇文章,在最後也會有些面試中常問的CSS相關面試題,看徹底文面試就不用慌了😗。css

目錄👇 html

在線卑微,若是以爲這篇文章對你有幫助的話歡迎你們點個贊👻前端

三大特性

: css大三特性是css最重要的部分,能夠說若是瞭解了這三大特性就對css撐握了一半,對於屬性只不過是記不記的住的事,而這個是重在理解。git

  • 層疊性:css樣式衝突採起的原則(後者覆蓋前者)
  • 繼承性:對於部分屬性樣式會有天生的繼承
  • 優先級:選擇器優先級算法

選擇器

在講這三個特性以前咱們須要來全面瞭解下選擇器。github

種類

下面我將選擇進行劃分爲三大部分,對於基本選擇器我就不說了,主要講下僞類選擇器,組合選擇器及它們各自的使用場景。面試

  • 基本選擇器
    • 類名:.box
    • 標籤: div
    • 屬性: input[type="eamil"] | a[href*="http://www.beige.world"]
    • ID: #box
  • 僞類選擇器
    • 結構僞類: :nth-child(n) | :nth-of-type(n) | :hover
    • 僞元素: ::before | ::after
  • 組合選擇器
    • 相鄰兄弟 A + B
    • 普通兄弟 A ~ B
    • 子選擇器 A > B
    • 後代選擇器 A B
基本選擇器

算了仍是講下屬性選擇器吧🤔,這個選擇器我在項目開發中仍是用到過的算法

直接看例子:編程

/* 匹配包含title屬性的a標籤 => <a title> */
a[title] {color: purple;}  


/* 存在href屬性而且屬性值爲"http://beige.world"的<a>標籤*/
/* <a href="http://beige.world"> */ 
a[href="http://beige.world"] {color: green;}


/* 存在href屬性而且屬性值包含"baidu"的<a>標籤*/
 /* <a href="https://baidu.com/we"> <a href="https://fanyi.baidu.com/we"> <a href="https://pan.baidu.com/we"> */ 
a[href*="baidu"] {font-size: 20px;}


/* 存在id屬性而且屬性值結尾是"-wrapper"的<div>標籤 */
 /* <div id="btn-wrapper"> <div id="menu-wrapper"> <div id="pic-wrapper"> */ 
div[id$="-wrapper"] {display: flex;}


/* 存在class屬性而且屬性值包含以空格分隔的"logo"的<div>元素 */
 /* <div id="aaa logo"> <div id="bbb logo"> */ 
 div[class~="logo"] { padding: 2px; }
複製代碼
僞類選擇器

結構僞類canvas

先講這兩比較做用相似的:nth-child(n) | nth-of-type(n)瀏覽器

結構

<ul>
  <li>1</li>
  <li>
    <p>a1</p>
    <div>b1</div>
    <p>a2</p>
    <div>b2</div>
  </li>
  <li>3</li>
  <li>4</li>
  <li>5</li>
</ul>
複製代碼

CSS

// 第一個li  =>  <li>1</li>
ul li:first-child { background-color: lightseagreen;} 
 // 最後一個li =>  <li>5</li>
ul li:last-child { background-color: lightcoral;}
// 第三個li => <li>3</li>
ul li:nth-child(3) { background-color: aqua; } 
// 第二個li下的第一個div(不是div標籤的都不算) => <div>b1</div>
ul li:nth-child(2) > div:nth-of-type(1) {background-color: red} 
複製代碼

它倆的區別

  • nth-child 選擇父元素裏面的第幾個子元素,無論是第幾個類型
  • nth-of-type 選擇指定類型的元素

下面講講nth-child()括號中的公式,這個算是這個選擇器的亮點了。

注意⚠:本質上就是選中第幾個子元素

  • n 能夠是數字、關鍵字、公式
  • n 若是是數字,就是選中第幾個
  • 常見的關鍵字有 even 偶數、odd 奇數
  • 常見的公式以下(若是 n 是公式,則從 0 開始計算)
  • 可是第 0 個元素或者超出了元素的個數會被忽略

對於這裏面的公式日常也用不到太複雜的,我說下個人技巧:nth-child(3n + 3); 這裏的n能夠看作幾個爲一組,3能夠看作選這組的第幾個。

例: nth-child(5n + 3) :5個爲一組,選一組中的第三個。 對於"-"號就表示選擇的是前面的。

組合選擇器

組合選擇器本質上就是經過鏈接符來對兩個選擇器進行組合

  • 子選擇器 A > B
  • 後代選擇器 A B

上面這兩我就不說了,相信你們都用爛了。主要說說下面這兩個。

  • 相鄰兄弟 A + B
  • 普通兄弟 A ~ B

結構

<div class="box1">
    <div>One</div>
    <div>Two!</div>
    <div>Three</div>
    <p>pppp</p>
  </div>
  <div class="box2">
    <div>One2</div>
    <p>pppp1</p>
    <div>Two2!</div>
    <p>pppp2</p>
  </div>
複製代碼

選擇器解析

<style>
    /* (+標識)符介於兩個選擇器之間,當第二個選擇器匹配的元素緊跟着第一個元素後面而且它們都是同一個父親 .box1 div:first-of-type(A元素) div(B元素) 匹配緊跟着A的B */
    .box1 div:first-of-type+div { color: red; }

    .box1 div:first-of-type+p { color: red;}  篩選不到的


    /* (~標識)符介於兩個選擇器之間,匹配第一個選擇器元素後面全部匹配第二個選擇器的同層級元素 .box2 div(A元素) p(B元素) 匹配全部A後面的B */
    .box2 div~p { color: seagreen; }
  </style>
複製代碼

好了,在講完這些選擇器以後咱們來看看它們的使用場景。

組合選擇器能夠用於:hover僞類操縱本身包含的子元素及之外的元素。舉個例子

<div id='a'>元素1
  <div id='b'>元素2</div>
</div>
<div id='c'>元素3
  <div id='b'>元素2</div>
</div>
<div>同級元素1</div>
<div>同級元素2</div>
<div>同級元素3</div>
</body>
複製代碼
#a:hover > #b{....}    
#a:hover ~ div{....} // 鼠標停留在a元素的時候讓全部同層級元素有某某樣式
// 防止選擇器層級替換了下面的樣式
#a:hover + #c{....} // 鼠標停留在a元素的時候讓同層級中的c元素有某某樣式
#a:hover + #c > #b{....} //  鼠標停留在a元素的時候讓同層級中的c元素下的b元素有某某樣式
複製代碼

上面這兩選擇器在作一些特效頁的時候應該是會用到的。

綜合例子

效果

結構

<body>
  <div class="img-box enter-box"> <!-- 懸浮在這個盒子的時候動態添加enter-box類名 -->
    <img src="http://resource.beige.world/imgs/beige.jpg" alt="">
    <div class="cover">
      <h3>標題名稱</h3>
      <p class="con">Bei Ge</p>
      <p class="brier">這裏放內容簡介,內容簡介,這裏放內容簡介,內容簡介,這裏放內容簡介,內容簡介</p>
      <div class="handle"><span>.</span><span>.</span><span>.</span></div>
    </div>
  </div>
  <!-- 其餘盒子 -->
  <div class="img-box">2</div> 
  <div class="img-box">3</div>
  <div class="img-box">4</div>
  <div class="img-box">5</div>
</body>
複製代碼

樣式

佈局樣式

<style>
     .img-box {
      position: relative;
      top: 100px;
      left: 200px;
      z-index: 1;
      display: inline-block;
      overflow: hidden;
      background: #70adc4;
      cursor: pointer;
      transition: transform .5s, box-shadow .3s;
    }

    .img-box img {
      width: 200px;
      height: 200px;
      opacity: 1;
      float: left;
    }
	
	.img-box .cover {
      width: 200px;
      height: 200px;
      padding: 15px;
      position: absolute;
      box-sizing: border-box;
      color: hotpink;
    }

    .img-box .cover h3 {
      margin-top: 10%;
      font-size: 24px;
      font-weight: bold;
      text-shadow: 0 0 2px #ccc;
      opacity: 0;
      transition: opacity .5s;
    }

    .img-box .cover .con {
      margin: 20px 0;
      font-style: italic;
      font-weight: bold;
      transform: translateX(-150%);
    }

    .img-box .cover .brier {
      font-size: 12px;
      transform: translateX(150%);
    }

    .img-box .cover .handle {
      position: absolute;
      right: 10px;
      bottom: -50px;
      font-size: 25px;
      transition: bottom 1s;
      /* 對於position的過渡動畫, 不能用position, 直接用位置屬性: left right top bottom */
    }
  </style>
複製代碼

定義了一個animation動畫

@keyframes textAnimation {
      /* 0% { transform: translateX(150%); } */
      100% {
        transform: translateX(0);
      }
}
複製代碼

懸浮在盒子設置樣式

.img-box:hover {
	transform: scale(1.1);
	box-shadow: 2px 2px 13px 3px #ccc;
}

.img-box:hover img {
	opacity: .5;
}

.img-box:hover .cover h3 {
 	opacity: 1;
}

.img-box:hover p {
	animation: textAnimation .6s ease-out forwards;
	/* forwards讓動畫停留在最後一幀 */
}

.img-box:hover .cover .handle {
  	bottom: 5px;
}

.enter-box:hover ~ .img-box {
  background-color: transparent;
  color: wheat;
}
.enter-box:hover + .img-box {
  color: red;
}
複製代碼

上面這個例子有些尚未講,可是相信你們以前也都學過,後文中也會說。主要會說些細節方面的東西。

  • flex(彈性佈局)
  • transform: translate3D rodate3D
  • animation(設定動畫)
  • 3D or 透視(perspective)

這裏須要注意在使用僞類Hover的注意點,在使用他影響子級元素的時候儘可能將選擇器寫全。例:

先看下效果😗

上面的效果相信你們都能寫出來,因此我要講的確定不是怎麼去實現這個效果,我要說下使用Hover時的一些細節。

結構比較簡單

flex類名用於佈局實現重置和水平居中,box: 綠色盒子;center: 紫色盒子 inner: 橙黃色盒子

<div class="box flex">
    <div class="center flex">
      <div class="inner"></div>
    </div>
</div>
複製代碼

咱們用了一個:hover讓鼠標虛浮的時候讓盒子變紅

.box:hover div {
	background-color: red;
}
複製代碼

這裏有一個問題不知道你們想過沒有,爲何我這段代碼只讓center盒子變紅了,inner爲何沒有變紅呢???

展開查看
由於CSS選擇器的優先級!複製代碼

咱們在實現的時候通常都會像下面這樣寫吧,這個時候使用僞類選擇器改變元素樣式的時候就要注意選擇器優先級的問題了。

.box .center {
      width: 150px;
      height: 150px;
      background-color: blueviolet;
}
.box .center .inner {
      width: 100px;
      height: 100px;
      background-color: coral;
}
複製代碼

這段代碼的優先級比 .box .center高,因此他也就只能覆蓋它了。

.box:hover div { 
      background-color: red;
}
複製代碼

相信咱們不少人若是在寫鼠標懸浮大盒子讓最裏面的inner盒子變色的時候,都會這麼寫吧:

.box:hover .inner { 
      background-color: red;
}
複製代碼

有用嗎?沒用!

注意⚠: 優先級仍是沒有.box .center .inner高。

層疊性

所謂層疊性是指多種CSS樣式的疊加。是瀏覽器處理衝突的一個能力,若是一個屬性經過兩個相同選擇器設置到同一個元素上,那麼這個時候一個屬性就會將另外一個屬性層疊掉

  • 原則:
    • 樣式衝突,遵循的原則是就近原則。 那個樣式離着結構近,就執行那個樣式。
    • 樣式不衝突,不會層疊
CSS層疊性最後的執行口訣:  長江後浪推前浪,前浪死在沙灘上。
複製代碼

繼承性

:子標籤會繼承父標籤的某些樣式,如文本顏色和字號。 想要設置一個可繼承的屬性,只需將它應用於父元素便可。簡單的理解就是: 子承父業

CSS繼承性口訣:  龍生龍,鳳生鳳,老鼠生的孩子會打洞
複製代碼

咱們恰當地使用繼承能夠簡化代碼,下降CSS樣式的複雜性。好比有不少後代元素都須要某個樣式,能夠給父級指定一個,這些孩子繼承過來就行了。

注意點:在CSS的繼承中不只僅是兒子能夠繼承, 只要是後代均可以繼承

可繼承的屬性

控制繼承

注意點: 對於天生自帶的繼承屬性咱們能夠控制它是否須要繼承

四個屬性

  • inherit: 被應用屬性繼承父級的該屬性(默認就是該值)
  • initial初始化,把應用屬性初始爲它默認的樣式,而且排除繼承的干擾(默認會繼承的屬性也不在默認繼承,而是表現出沒有任何設置時候的默認樣式)
  • unset:意思是恢復其本來的繼承方式。對color屬性而言,就至關於inherit;而對於諸如border這樣默認不繼承的屬性,就至關於initial
  • revert: 效果等同於unset且瀏覽器支持有限,這裏不作演示

效果圖

演示

<ul style="color: green;">
    <li class="default">Default <a href="#">link</a> color</li>
    <li class="inherit">Inherit the <a style="color: inherit;" href="#">link</a> color</li>
    <li class="initial">Reset the <a style="color: initial;" href="#">link</a> color</li>
    <li class="unset">Unset the <a style="color: unset;" href="#">link</a> color</li>
</ul>
複製代碼
  • default中的a標籤沒有寫默認爲inherit屬性,可是使用了瀏覽器預設樣式表:能夠理解爲瀏覽器幫咱們爲<a>寫了個style,其優先級天然就高於其父元素了。
  • inherit中的a標籤在行內寫了inherit,因而使用其父(或祖父,etc)元素的顏色值,在這裏是綠色;
  • initial中的a標籤使用color屬性初始值(黑色), 注意不要混淆屬性初始值和瀏覽器樣式表指定值,樣式預設表是瀏覽器事先寫好的樣式,可是我color默認值就是黑色啊。
  • unset,意思是恢復其本來的繼承方式。對color屬性而言,就至關於inherit;而對於諸如border這樣默認不繼承的屬性,就至關於initial。

若是咱們須要控制元素全部屬性的繼承使用all屬性

.inherit a {
	all: initial; 
	/* 將全部的屬性都恢復成默認值(天生繼承也再也不繼承) */
    /* 行內設置過的除外:你的層級幹不過人家 */
}
複製代碼
繼承的權重是0

這個不難,可是忽略很容易繞暈。其實,咱們修改樣式,必定要看該標籤有沒有被選中。

(1) 若是選中了,那麼以上面的公式來計權重。誰大聽誰的。 (2) 若是沒有選中,那麼權重是0,由於繼承的權重爲0.

控制繼承在咱們封裝本身的組件的時候是會用到的,咱們在封裝組件須要沿用樣式,有些默認狀況下不可繼承父元素的屬性:box-sizing,這個其實用的就不少。

優先級

要想了解優先級,確定得了解選擇器;可是選擇器很是多的,前面列舉的是平常開發用的比較多,其餘的你可能一生都用不到,這裏貼出C1~C4的選擇器,感興趣的同窗能夠看看。

定義CSS樣式時,常常出現兩個或更多選擇器應用在同一元素上,此時,

  • 選擇器相同,則執行層疊性(後者覆蓋前者)
  • 選擇器不一樣,就會出現優先級的問題。

權重計算公式

關於CSS權重,咱們須要一套計算公式來去計算,這個就是 CSS Specificity(特殊性)

標籤選擇器 計算權重公式
繼承或者 * 0,0,0,0
每一個元素(標籤選擇器) 0,0,0,1
每一個類,結構僞類(如:hover),屬性選擇器[type="number"] 0,0,1,0
每一個ID 0,1,0,0
每一個行內樣式 style="" 1,0,0,0
h1 + p::first-line 0,0,0,3
li > a[href*="beige.world"] > .inline-warning 0,0,2,2
每一個!important 重要的 ∞ 無窮大

值從左到右,左面的最大,一級大於一級,數位之間沒有進制,級別之間不可超越。

經常使用的選擇器記法

  • 行內: 1,0,0,0
  • #id: 0,1,0,0
  • .class | :hover | :nth-child(): 0,0,1,0 (:hover這種一個冒號叫結構僞類)
  • ::after | ::before | ::first-line: 0,0,0,1 (這種兩冒號的叫僞元素,在書寫的時候雖然你能夠寫一個冒號可是瀏覽器仍是給你補上去了,本質上就是兩冒號)

權重疊加

咱們常常用組合選擇器,是有多個基礎選擇器組合而成,那麼此時,就會出現權重疊加。

就是一個簡單的加法計算

  • div ul li ------> 0,0,0,3
  • .nav ul li ------> 0,0,1,2
  • a:hover -----—> 0,0,1,1
  • .nav a ------> 0,0,1,1

注意⚠: 數位之間沒有進制 好比說: 0,0,0,5 + 0,0,0,5 = 0,0,0,10 而不是 0,0, 1, 0, 因此不會存在10個div能遇上一個類選擇器的狀況。

important適用優先級💡

#id .box div {
    color: red !important;
}

#id div.box div {
    color: green !important; // 使用這個選擇器中的顏色
}
複製代碼

通關答題

下面來幾道題,全對纔算經過了噢😗

<style type="text/css"> .c1 .c2 div{ color: blue; } div #box3 { color:green; } #box1 div { color:yellow; } </style>
</head>
<body>
<div id="box1" class="c1">
  <div id="box2" class="c2">
    <div id="box3" class="c3">
      文字
    </div>
  </div>
</div>
</body>
複製代碼

什麼顏色??

展開查看答案
yellow 上面兩選擇器的層級都是同樣的, 後者覆蓋前者 複製代碼
<style type="text/css"> #father #son{ color:blue; } #father p.c2{ color:black; } div.c1 p.c2{ color:red; } #father{ color:green !important; } </style>
</head>
<body>
<div id="father" class="c1">
  <p id="son" class="c2">
    試問這行字體是什麼顏色的?
  </p>
</div>
</body>
複製代碼
展開查看答案
blue 複製代碼
<body>
  <style>
    div.parent {
      width: 300px;
      height: 300px;
      border: 10px solid #000;
      font-size: 46px;
      text-shadow: 3px 13px 4px green;
      box-sizing: border-box
    }
    div.child {
      width: 200px;
      height: 200px;
      background-color: brown;
      border: 5px solid #000;
      width: inherit;
      box-sizing: inherit;
      font-size: 80px;
    }
  </style>
</head>
  <div class="parent">
    <div id="child" class="child">123</div>
  </div>

  <!-- 
    child: 字體多大? 有沒有文字陰影? 真實內容的寬高是多少?
   -->
</body>
複製代碼
展開查看答案
字體:80,有文字陰影,真實內容的寬:290px 高190px複製代碼

講下這最後一題

文字陰影有:由於從父元素中繼承到了,字體: 80px;

真實內容寬290px, 高190px

常問的屬性

  • flex(彈性佈局)
  • transform: translate3D rodate3D
  • animation(設定動畫)
  • 3D or 透視(perspective)

flex

flex佈局相信你們也都用爛了,用來讓盒子垂直和水平居中好用的一批

父項經常使用屬性

  • flex-direction:設置主軸的方向
  • justify-content:設置主軸上的子元素排列方式
  • flex-wrap:設置子元素是否換行
  • align-content:設置側軸上的子元素的排列方式(多行)
  • align-items:設置側軸上的子元素排列方式(單行)
  • flex-flow:複合屬性,至關於同時設置了 flex-direction 和 flex-wrap

flex-direction

在 flex 佈局中,是分爲主軸和側軸兩個方向,一樣的叫法有 : 行和列、x 軸和y 軸

  • 默認主軸方向就是 x 軸方向,水平向右
  • 默認側軸方向就是 y 軸方向,水平向下

<img src="./imgs/13.JPG">

: 主軸和側軸是會變化的,就看 flex-direction 設置誰爲主軸,剩下的就是側軸。而咱們的子元素是跟着主軸來排列的

flex-wrap設置是否換行

  • 默認狀況下,項目都排在一條線(又稱」軸線」)上。flex-wrap屬性定義,flex佈局中默認是不換行的。
  • nowrap 不換行
  • wrap 換行

justify-content 設置主軸上的子元素排列方式

<img src="./imgs/14.jpg">

效果圖

: 這裏講下space-aroundspace-evenly

  • space-around:項目之間的間距爲左右兩側項目到容器間距的2倍。

  • space-evenly:項目兩側之間的間距與項目與容器兩側的間距相等,至關於除去項目寬度和容器和項目的兩側間距,剩下的平均分配了剩餘寬度做爲項目左右margin。

**設置側軸上的子元素排列方式:align-items(單行)/align-content(多行) **

上圖寫能設置多行只能用於子項出現 換行 的狀況(多行),在單行下是沒有效果的。

效果跟上面是同樣的只不過是方向換了,上面是元素在主軸上排列,這個是在側抽上,至於側軸是否是Y軸就看你的flex-direciton怎麼設置的了

子項常見屬性

  • flex(複合屬性): 默認: flex: 0 1 auto;
    • flex-grow
    • flex-shrink
    • flex-basis
  • align-self:控制子項本身在側軸的排列方式
  • order:定義子項的排列順序(先後順序), 0是第一個

flex-grow

默認0,用於決定項目在有剩餘空間的狀況下是否放大,默認不放大;注意,即使設置了固定寬度,也會放大。

假設第一個項目默認爲0,第二個項目爲flex-grow:2,最後一個項目爲1,則第二個項目在放大時所佔空間是最後項目的兩倍。

能夠這麼理解:

  • flex: 1 => 在剩餘的空間裏我就佔一份
  • flex: 2 => 在剩餘的空間裏我就佔兩份
  • flex: 3 => 在剩餘的空間裏我就佔三份
假設三個盒子分別都設置了上面的屬性: 那就將剩餘空間分紅6份, 各佔本身的份數

假設前兩個沒有設置, 就最後一個設置了flex: 3 === flex: 1, 那就將剩餘空間都給它
複製代碼

flex-shrink

默認1,用於決定項目在空間不足時是否縮小,默認項目都是1,即空間不足時你們一塊兒等比縮小;注意,即使設置了固定寬度,也會縮小。但若是某個項目flex-shrink設置爲0,則即使空間不夠,自身也不縮小。

上圖中第二個項目flex-shrink爲0,因此自身不會縮小。

flex-basis

默認auto,用於設置項目寬度,默認auto時,項目會保持默認寬度,或者以width爲自身的寬度,但若是設置了flex-basis,權重會width屬性高,所以會覆蓋widtn屬性。

上圖中先設置了flex-basis屬性,後設置了width屬性,但寬度依舊以flex-basis屬性爲準。

注意⚠: 若是當容器中有多個盒子而且還寬度100%, flex-basis會被影響, 以下圖

解決辦法就是在咱們設置flex-basis寬度時, 最好給他設置flex-shrink爲0不縮放

transform

2D的屬性相信你們都會用了, 本文主要深究transform的3D屬性

  • 透視:perspctive
  • 3D呈現:transfrom-style
  • 3D 位移:translate3d(x, y, z)
  • 3D旋轉:rotate3d(x, y, z)

透視(perspective)

在講3D之間先來了解一下透視(視距),只有瞭解了透視咱們才能理解3D的物體投影在2D平面上

  • 透視也稱爲視距,所謂的視距就是人的眼睛到屏幕的距離
  • 實際上模仿人類的視覺位置,可視爲安排一直眼睛去看
  • 距離透視點越近的在電腦平面成像越大,越遠成像越小
  • 透視的單位是像素

注意: 透視須要寫在被視察元素的父盒子上面

拿圖說話👇

  • d:就是視距,視距就是指人的眼睛到屏幕的距離
  • z:就是 z 軸,z 軸越大(正值),咱們看到的物體就越大

來個栗子🌰

給實例的父元素設置: perspective: 200px;
複製代碼

上面咱們在div的父盒子上設置了perspective,也就是說從3D成像的角度來說咱們人眼距離屏幕div是200的視距,translate3D設置Z軸讓div往前挪了100,視距變小距離咱們人眼距離也就越小,因此看到的div也就變大了。 (能夠想像成在500米遠看見的人, 和5米看見的人。)

translate3d(x, y, z)

3D的特色

  • 近大遠小
  • 物體和麪遮擋不可見

三維座標系

  • x 軸:水平向右 -- 注意:x 軸右邊是正值,左邊是負值
  • y 軸:垂直向下 -- 注意:y 軸下面是正值,上面是負值
  • z 軸:垂直屏幕 -- 注意:往外邊的是正值,往裏面的是負值

3D 呈現 transform-style

transform-style:控制子元素是否開啓三維立體環境,代碼寫給父級,可是影響的是子盒子

  • transform-style: flat 表明子元素不開啓 3D 立體空間,默認的
  • transform-style: preserve-3d 子元素開啓立體空間

效果圖

body {
  perspective: 500px;
}

.box {
  position: relative;
  width: 200px;
  height: 200px;
  margin: 100px auto;
  transition: all 2s;
  /* 讓子元素保持3d立體空間環境 */
  transform-style: preserve-3d;
}

.box:hover {
  transform: rotateY(60deg);
}

.box div {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: pink;
}

.box div:last-child {
  background-color: purple;
  transform: rotateX(60deg);
}
複製代碼

rotate3d(x, y, z)

3D 旋轉指可讓元素在三維平面內沿着 x 軸、y 軸、z 軸 或者自定義軸進行旋轉

  • transform: rotate3d(x, y, z, 45deg)` -- 沿着自定義軸旋轉 45 deg 爲角度

例子:

<ul>
	<li>
		<div class="box">
		<div class="front">公衆號:</div>
		<div class="bottom">前端自學驛站</div>
		</div>
	</li>
</ul>
複製代碼
ul li {
	float: left;
	margin: 0 5px;
	width: 120px;
	height: 35px;
	list-style: none;
	/* 一會咱們須要給box 旋轉 也須要透視 乾脆給li加 裏面的子盒子都有透視效果 */
	perspective: 500px;
}

.box {
	position: relative;
	width: 100%;
	height: 100%;
	transform-style: preserve-3d;
	transition: all .4s;
}

.box:hover {
	transform: rotateX(90deg);
}

.front,
.bottom {
	position: absolute;
	left: 0;
	top: 0;
	width: 100%;
	height: 100%;
}

.front {
	background-color: pink;
	z-index: 1;
	transform: translateZ(17.5px);
}

.bottom {
	background-color: purple;
	/* 這個x軸必定是負值 */
	/* 咱們若是有移動 或者其餘樣式,必須先寫咱們的移動 */
	transform: translateY(17.5px) rotateX(-90deg);
}
複製代碼

animation

動畫(animation)是 CSS3 中最具顛覆性的特徵之一,可經過設置多個節點來精確的控制一個或者一組動畫,從而實現複雜的動畫效果, 先定義動畫在調用定義好的動畫

動畫序列

0% 是動畫的開始,100 % 是動畫的完成,這樣的規則就是動畫序列

  • 在 @keyframs 中規定某項 CSS 樣式,就由建立當前樣式逐漸改成新樣式的動畫效果
  • 動畫是使元素從一個樣式逐漸變化爲另外一個樣式的效果,能夠改變任意多的樣式任意多的次數
  • 用百分比來規定變化發生的時間,或用 fromto,等同於 0% 和 100%
@keyframes move{
	0% {
		transform: translate(0px)
	}
	form {
		transform: translate(0px)
	}
	
	100% {
		transform: translate(500px, 0)
	}
	to {
		transform: translate(500px, 0)
	}
}
複製代碼

動畫常見屬性

動畫簡寫方式

/* animation: 動畫名稱 持續時間 運動曲線 什麼時候開始 播放次數 是否反方向 起始與結束狀態 */
animation: name duration timing-function delay iteration-count direction fill-mode
複製代碼

除了名字,持續時間,什麼時候開始有嚴格順序要求其它隨意

CSS實現掃描二維碼

效果

代碼篇幅過長我放到gitHub倉庫了,你們能夠pull下來自行研究。

地址:github.com/it-beige/bl…

面試常問題

BFC相關

BFC(Block formatting context)直譯爲"塊級格式化上下文"。

在講BFC以前得先說下display的屬性值,只有它符合成爲條件才資格觸發BFC機制

display屬性值

那些屬性值會具備BFC的條件

不是全部的元素模式都能產生BFC,w3c 規範: display 屬性爲 block, list-item, table 的元素,會產生BFC.

你們有沒有發現這個三個都是用來佈局最爲合理的元素,由於他們就是用來可視化佈局。注意其餘的,display屬性,好比 line 等等,他們建立的是 IFC ,咱們下面研究。

這個BFC 有着具體的佈局特性:

有寬度和高度,有 外邊距margin 有內邊距padding 有邊框 border。就比如,你有了練習武術的體格了。 有潛力,有資質。

什麼狀況下可讓元素產生BFC

以上盒子具備BFC條件了,就是說有資質了,可是怎樣觸發纔會產生BFC,從而創造這個封閉的環境呢?

就比如,你光有資質還不行,你須要必定額外效果才能出發的武學潛力,要麼你掉到懸崖下面,撿到了一本九陰真經,要麼你學習葵花寶典,欲練此功必先....

一樣,要給這些元素添加以下屬性就能夠觸發BFC。

  • float屬性不爲none
  • position爲absolute或fixed
  • display爲inline-block, table-cell, table-caption, flex, inline-flex
  • overflow不爲visible。

BFC元素所具備的特性

BFC佈局規則特性:

  • 在BFC中,盒子從頂端開始垂直地一個接一個地排列
  • 盒子垂直方向的距離由margin決定。屬於同一個BFC的兩個相鄰盒子的margin會發生重疊
  • 在BFC中,每個盒子的左外邊緣(margin-left)會觸碰到容器的左邊緣(border-left)(對於從右到左的格式來講,則觸碰到右邊緣)。
    • BFC的區域不會與浮動盒子產生交集,而是緊貼浮動邊緣。
    • 計算BFC的高度時,天然也會檢測浮動或者定位的盒子高度

它是一個獨立的渲染區域,只有Block-level box參與, 它規定了內部的Block-level Box如何佈局,而且與這個區域外部絕不相干。

白話文: 孩子在家裏願意怎麼折騰都行,可是出了家門口,你就的乖乖的,不能影響外面的任何人。
複製代碼

BFC的主要用途

(1) 清除元素內部浮動

只要把父元素設爲BFC就能夠清理子元素的浮動了,最多見的用法就是在父元素上設置overflow: hidden樣式

主要用到

計算BFC的高度時,天然也會檢測浮動或者定位的盒子高度。
複製代碼

(2) 解決外邊距合併(塌陷)問題

主要用到

盒子垂直方向的距離由margin決定。屬於同一個BFC的兩個相鄰盒子的margin會發生重疊
複製代碼

屬於同一個sBFC的兩個相鄰盒子的margin會發生重疊,那麼咱們建立不屬於同一個BFC,就不會發生margin重疊了。

(3) 製做右側自適應的盒子問題

主要用到

普通流體元素BFC後,爲了和浮動元素不產生任何交集,順着浮動邊緣造成本身的封閉上下文
複製代碼

BFC 總結

BFC就是頁面上的一個隔離的獨立容器,容器裏面的子元素不會影響到外面的元素。反之也如此。包括浮動,和外邊距合併等等,所以,有了這個特性,咱們佈局的時候就不會出現意外狀況了。

IFC相關

IFC(inline Formatting Context)叫作「行級格式化上下」相對BFC比較簡單且問的也不是不少,這裏大該作個瞭解

佈局規則以下:

  • 內部的盒子會在水平方向,一個個地放置(默認就是IFC);
  • IFC的高度,由裏面最高盒子的高度決定(裏面的內容會撐開父盒子);
  • 當一行不夠放置的時候會自動切換到下一行;

哪些屬性開啓了性能加速

何爲硬件加速:就是將瀏覽器的渲染過程交給GPU(Graphics Processing Unit)處理,而不是使用自帶的比較慢的渲染器。這樣就可使得animationtransition更加順暢

咱們能夠在瀏覽器中用CSS開啓硬件加速,使GPU發揮功能,從而提高性能

所謂GPU,就是圖形處理器的縮寫,至關於PC中的顯卡。手機中的GPU也是爲了對圖形、圖像處理而存在的,所謂強制渲染,就是hwa(hardware acceleration硬件加載)的一種,其存在的意義就是爲了分擔cpu的負擔,其原理是經過GPU對軟件圖形的處理來減輕CPU的負擔。從而使應用軟件可以以更快的速度被處理,以達到提速的目的。

硬件加速的原理

瀏覽器接收到頁面文檔後,會將文檔中的標記語言解析爲DOM樹。DOM樹和CSS結合後造成瀏覽器構建頁面的渲染樹。渲染樹中包含大量的渲染元素,每一個渲染元素會被分到一個圖層中,每一個圖層又會被加載到GPU造成渲染紋理,而圖層在GPU中transform是不會觸發repaint的,最終這些使用transform的圖層都會由獨立的合成器進程進行處理, CSS transform會建立了一個新的複合圖層,能夠被GPU直接用來執行transform操做

瀏覽器何時會建立一個獨立的複合圖層呢?事實上通常是在如下幾種狀況下:

  • 3D或者CSS transform
  • <video><canvas>標籤
  • css filters(濾鏡效果)
  • 元素覆蓋時,好比使用了z-index屬性

爲何硬件加速會使頁面流暢

由於transform屬性不會觸發瀏覽器的repaint(重繪),而絕對定位absolute中的left和top則會一直觸發repaint(重繪)。

爲何transform沒有觸發repaint呢?

簡而言之,transform動畫由GPU控制,支持硬件加載,並不須要軟件方面的渲染。並非全部的CSS屬性都能觸發GPU的硬件加載,事實上只有少數的屬性能夠,好比transform、opacity、filter

如何用CSS開啓硬件加速

CSS animation、transform以及transition不會自動開啓GPU加速,而是由瀏覽器的緩慢的軟件渲染引擎來執行,那咱們怎樣才能夠切換到GPU模式呢,不少瀏覽器提供了某些觸發的CSS規則。

當瀏覽器檢測到頁面中某個DOM元素應用了某些CSS規則時就會開啓,最顯著的特徵的元素是3D變化。

.cube{
    translate3d(250px,250px,250px);
    rotate3d(250px,250px,250px,-120deg)
    scale3d(0.5,0.5,0.5);
}
複製代碼

可能在一些狀況下,咱們並不須要對元素應用3D變幻的效果,那怎麼辦呢?這時候咱們可使用「欺騙」瀏覽器來開啓硬件加速。雖然咱們可能不想對元素應用3D變幻,可咱們同樣能夠開啓3D引擎。例如咱們能夠用transform:translateZ(0);來開啓硬件加速

.cube{
   transform: translateZ(0);
}
複製代碼

寫在最後

若是文章中有那塊寫的不太好或有問題歡迎你們指出,我也會在後面的文章不停修改。也但願本身進步的同時能跟大家一塊兒成長。喜歡我文章的朋友們也能夠關注一下

我會很感激第一批關注個人人。此時,年輕的我和你,輕裝上陣;然後,富裕的你和我,滿載而歸。

參考文章

CSS繼承控制:inherit、initial和unset

一篇文章弄懂flex佈局

往期文章

【前端體系】從一道面試題談談對EventLoop的理解 (更新了四道進階題的解析)

【前端體系】從地基開始打造一座萬丈高樓

【前端體系】正則在開發中的應用場景可不僅是規則校驗

「函數式編程的實用場景 | 掘金技術徵文-雙節特別篇」

相關文章
相關標籤/搜索