CSS中的一些小細節

1、CSS排版原理

box

box-sizing

  • 改變盒模型計算方式
  • 取值:border-box | content-box
  • 初始值:content-box

舉個例子:css

<div class="box a">Box A</div>
<div class="box b">Box B</div>

<style>
  .box {
    width: 100px;
    height: 100px;
    padding: 10px;
    border: 10px solid #f66;
    background: #f99;
    margin: 1em;
  }
  .b {
    box-sizing: border-box;
  }
</style>

演示結果:html

box

box-sizing mdn文檔css3

2、一些容易被忽視的小細節

2.1 下面代碼,p標籤的高度是多少?

<p>Some text</p>

<style>
p {
  height: 100%;
  background: red;
}
</style>

解析:默認狀況下body是沒有高度只有寬度。因此p標籤的父級是body默認高度爲0,因此p的高度也是0。
解決辦法:能夠設置height: 100vh,使用一些屏幕的單位如vh vw,一個屏幕的高度是100vhcanvas

2.2 下面代碼中padding-top值多少?

<div> </div>

<style>
  div {
    background: red;
    padding-top: 100%;
  }
</style>

以上代碼padding-top等於父容器body的寬度,實現了一個響應式的正方形 瀏覽器

解析:padding不論是padding-top仍是padding-left,它的百分比都是根據父容器的'寬度'來決定的。ide

使用場景:能夠利用padding的百分比來作出一些固定寬高比的盒子。svg

2.3 Margin Collapse 合併

<div class="a"></div>
<div class="b"></div>

<style>
  .a{
    background: lightblue;
    height: 100px;
    margin-bottom: 100px;
  }
  .b {
    background: coral;
    height: 100px;
    margin-top: 100px;
  }
</style>
  • 之前是爲了讓報紙、排版而設定的
  • a與b之間的高度仍是100px,這就是margin合併。

2.4 利用border能夠製做任意角度的三角形

<div class="box"></div>

<style>
  .box {
    border-width: 50px;
    border-style: solid;
    border-color: #f35 #269 #649 #fa0;
    width: 0px;
    height: 0px;
    margin: 1em auto;
  }
</style>

border

經過給border的其餘的三條邊設置透明色,就能夠製做任意角度的三角形。佈局

思考題:這個圖標怎麼作?字體

reat

方法1:使用border構造相間的三角形,而後使用overflow-hiddenborder-radius剪裁成圓。另外注意水平、垂直居中的實現方式。flex

<div id="warning">
  <div class="bg"></div>
  <div class="bg"></div>
  <div class="bg"></div>
</div>

<style>
#warning {
  position: relative;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 200px;
  height: 200px;
  overflow: hidden;
  border-radius: 50%;
}

#warning .bg {
  position: absolute;
  width: 0;
  height: 0;
  top: -73.2px;
  left: 0px;
  border-top: solid 173.2px rgb(246, 226, 54);
  border-left: solid 100px transparent;
  border-bottom: solid 173.2px black;
  border-right: solid 100px transparent;
} 

#warning .bg:nth-child(1) {
  transform: rotate(0deg);
} 

#warning .bg:nth-child(2) {
  transform: rotate(120deg);
} 

#warning .bg:nth-child(3) {
  transform: rotate(240deg);
}
</style>

方法2:利用svg的虛線來作,這個方法比較靈巧,不容易理解,請屢次調試stroke和stroke-dasharray的值加深理解。

<svg viewBox="0 0 64 64" class="warning">
  <circle r="25%" cx="50%" cy="50%"/>
</svg>

<style>
.warning {
  width: 300px;
  background: black;
  border-radius: 50%;
}

.warning circle {
  fill: none;
  stroke: yellow;
  stroke-width: 32;
  stroke-dasharray: 26%;
}
</style>

方法3:利用css3新特性:錐形漸變。

<div></div>

<style>
div {
  padding-top: 100%;
  background: repeating-conic-gradient(black 0 60deg, yellow 0 120deg);
  border-radius: 50%;
}
</style>

方法4:也可使用canvas和js等等。

3、視覺格式化模型

  • 視口(viewport): 瀏覽器的可視區域
  • 塊級元素

    • 會被格式化成塊狀的元素
    • 例如 p div section
    • display設置爲blocklist-itemtable將元素變爲塊級
  • 行級元素

    • 不會爲其內容生成塊級框
    • 讓其內容分佈在多行中
    • display設置爲inlineinline-blockinline-table使元素變爲行級
  • 盒子的生成

    • 每一個塊級元素生成一個主塊級盒,用它來包含子級盒
    • 每一個行級元素生成一個行級盒,行級盒分佈於多行
  • 塊級盒子中的子盒子的生成

    • 塊級盒子中能夠包含多個子塊級盒子
    • 也能夠包含多個行級盒子
    • 不在行級元素裏面的文字,會生成匿名行級盒。好比 <p>Some <em>Text</em></p>,some在塊級盒子裏,而且沒有被行級元素包裹,因此會生成匿名的行級盒子。
    • 塊級盒子中不能同時包含塊級和行級盒子。遇到這種狀況時,會生成匿名塊級盒來包含行級盒。好比 <div><h1>標題</h1><span>2018-5-12</span></div>
  • 行級盒子內的子盒子的生成

    • 行級盒子內能夠包含行級盒子
    • 行級盒子包含一個塊級盒子時,會被塊級盒子拆成兩個行級盒子,這兩個盒子又分別被匿名塊級盒包含。

舉個栗子🌰:

<span>
    aaaaa
    <div>
        bbb
    </div>
    ccc
</span>

img

行級盒子spandiv分割成兩個行級盒子aaa,bbb,這兩個行級盒子又被匿名塊級盒子包含,因此呈三個塊級元素佈局。

  • display屬性

    • block 生成塊級盒
    • inline 生成行級盒
    • inline-block 生成行級盒,裏面內容能夠是塊級盒
    • none 在排版時將元素忽略
  • 經過css生成盒子

    • ::before 在元素內部的前面添加一個行盒
    • ::after 在元素內部的後面添加一個行盒
    • display:list-item 這個就是列表前方的小圓點,就是給li前面添加一個行盒,生成小圓點。

舉個栗子🌰

<p><span>Learn to Code HTML & CSS is a simple and comprehensive
guide dedicated to helping beginners learn HTML and CSS.
Outlining the fundamentals, this guide works through all common
elements of front-end design and development.</span></p>

<style>
  p {
    line-height: 2;
    padding: 1em;
    border: 2px solid #00f;
    background: #ccf;
  }
  span {
    background: #fcc;
    border: 2px solid #f00;
  }
</style>

img

塊級盒子能夠包含多個行級盒子,行級盒子能夠分佈多行。

4、定位模式

  • 常規流
  • 浮動
  • 絕對定位

4.1 常規流

  • 除根元素、浮動元素和絕對定位元素外,其它元素都在常規流以內(in-flow)
  • 而根元素、 浮動和絕對定位的元素會脫離常規流(out of flow)
  • 常規流中的盒子,屬於塊級格式化上下文或行級格式化上下文

4.2 塊級格式化上下文

  • Block Formatting Contex (BFC)
  • 盒子在容器(包含塊)內從上到下一個接一個地放置
  • 兩個兄弟盒之間的豎直距離由 margin 屬性決定
  • 同一個 BFC 內垂直 margin 會合並
  • 盒子的左外邊緣挨着容器(包含塊)的左邊

4.3 行級格式化上下文

  • Inline Formatting Context (IFC)
  • 盒子一個接一個水平放置
  • 盒之間的水平 marginborderpadding都有效
  • 同一行的盒子所在的矩形區域叫行盒(Line box)
  • 當一個行盒放不下上下文內全部盒子時,會被分到多個垂直堆疊的行盒裏
  • 行盒內的水平分佈由text-align屬性決定
  • 若是一個行級塊沒法分割(單詞、inline-block),該元素會被做爲一個總體決定分佈在哪個行盒

4.4 float

  • 浮動元素從常規流中脫離,被漂浮在容器(包含塊)左邊或右邊
  • 浮動盒會一直漂到其外邊緣捱到容器邊緣或另外的浮動盒
  • 浮動元素不會影響其後面的流內塊級盒
  • 可是浮動元素後面的行級盒子會變短以避開浮動元素

總結一下:浮動元素後面的塊級元素不會‘發現’浮動元素,而行級盒子會避開前面的浮動元素。

舉個栗子🌰:

<section>
  <img src="http://p0.qhimg.com/t0117c2689d8703d551.jpg"
    width="120" alt="house">
  <p><span>莫哈韋沙漠不只緯度較高,並且溫度要稍微低些,是命名該公園的
  短葉絲蘭——約書亞樹的特殊棲息地。約書亞樹以從茂密的森林到遠遠
  間隔的實例等各類形式出現。除了約書亞樹森林以外,該公園的西部包
  括加州沙漠裏發現的最有趣的地質外觀。</span></p>
</section>

<style>
  img {
    float: left;
  }
  p {
    font-size: 14px;
    line-height: 1.8;
    border: 1px solid;
  }
</style>

代碼演示
img

解釋一下:
上述代碼中,<p>沒有由於<img>的而影響定位,<p>並無‘發現’<img>圖片,而<span>裏的文字‘避開’了<img>

利用float能夠作圖文混排效果

4.5 clear

  • 指定元素哪一邊不能與以前的浮動框相鄰
  • 取值: left | right | both

4.6 清除浮動

  • 最經常使用的清除浮動的方法 clearfix
/* 凡是遇到清除浮動,就這麼寫 */ 
.clearfix::after {
  content: ' ';
  display: block;
  clear: both;
  height:0;
  overflow: hidden;
}
  • 下面這些屬性會觸發bfc,bfc裏面的浮動不會溢出影響外部的盒子的排版,這樣與清除浮動的效果是同樣的。

    • overflow: hidden/auto
    • display: inline-block
    • float: left/right

4.7 塊級格式化上下文(BFC) 的特性

  • BFC 內的浮動不會影響到BFC外部的元素
  • BFC 的高度會包含其內的浮動元素
  • BFC 不會和浮動元素重疊
  • BFC 能夠經過 overflow:hidden 等方法建立

4.8 BFC 的建立

  • 浮動框
  • 絕對定位框
  • 非塊級的塊容器 inline-block
  • overflow 屬性非 visible 的塊框

4.9 BFC的做用

bfc就是爲了把本身裏面的東西‘封閉’起來,不與外界作過多的‘干擾’。

  • 清除浮動
  • 防止 margin 摺疊
  • 兩欄佈局

5、定位和堆疊

  • position

    • static 非定位,默認值
    • relative 相對定位(相對本身)
    • absolute 絕對定位,相對非 static 祖先元素定位
    • fixed 相對於視口絕對定位
  • z-index 堆疊層次

    • 爲定位元素指定其在 z 軸的上下等級
    • 用一個整數表示,數值越大,越靠近用戶
    • 初始值爲 auto,能夠爲負數、0、正數

5.1 思考一個問題:是否是z-index越大,就越在上面呢?

來看下面一坨代碼,重點看有z-index的元素

<nav>
  <ul>
    <li>z-index: 2</li>
  </ul>
</nav>

<div id="dialog">
  z-index: 1
</div>

<style>
  nav {
    position: fixed;
    top: 0;
  }
  nav ul {
   position: absolute;
    z-index: 2;
    top: 0;
    left: 0;
    background: red;
    padding: 1em;
    width: 10em;
  }
  #dialog {
    position: absolute;
    z-index: 1;
    top: 5em;
    left: 5em;
    background: blue;
    height: 10em;
    width: 10em;
  }

  body {
    color: #fff;
  }
  li {
    margin: 1em 0;
    list-style:none;
  }
  #dialog {
    padding: 1em;
  }
  ul {
    padding: 1em;
  }
</style>

5.2 結果爲何是z-index: 1在上面呢?

img

  • 在排版的時候,瀏覽器不僅是比較z-index的值,是比較同一個堆疊上下文的z-index的值的大小。
  • 上述例子中,應該是<nav>div#dialog比較,<nav>中的z-index是默認值auto, div#dialog中的z-index1,因此藍色框在上面。nav裏面的元素的z-index再大也不能排在上面,由於他的父級‘不行’😁😀。
  • 可是若是把nav裏的position設置爲absolute呢?你能夠試試改一下上面的代碼,得出結果是否是大吃一驚呢?爲何紅色就上去了呢?

img

  • 由於positionfixedsticky 的元素不用z-index就會建立堆疊上下文,這樣<div><nav>進行z-index比較。
  • positiong:absolute的元素須要同時設定z-index纔會建立堆疊上下文,nav中沒有設置z-index,因此不會建立堆疊上下文,而<nav>裏面的<ul>既包含了定位與z-index屬性,因此div就會和<nav>裏面的<ul>做比較,這樣紅色框會在藍色框上面。

5.3 建立堆疊上下文

  • Root 元素
  • relative 或 absolute 且 z-index 不是 auto 的元素
  • position 爲 fixed 或 sticky 的元素
  • 設置了某些 CSS3 屬性的元素,好比 opacity、transform、animation、will-change 等
  • flexbox 的子元素且 z-index 不是 auto

有以上特色的都會建立堆疊上下文

5.4 繪製層級

在每個堆疊上下文中,從下到上:

  • 造成該上下文的元素的 border 和 background
  • z-index 爲負值的子堆疊上下文
  • 常規流內的塊級元素非浮動子元素
  • 非定位的浮動元素
  • 常規流內非定位行級元素
  • z-index 爲 0 的子元素或子堆疊上下文
  • z-index 爲正數的子堆疊上下文

6、行內排版

6.1 全部的文字都是基於baseline來排版的。

img

6.2 line-height

img

6.3 line-box中盒子擺放

img

  • 對於圖片、不一樣的文字都是基於同一個baseline來佈局
  • 圖片的baseline是圖片的底邊
  • 對於inline-block的盒子,他是基於文字的最後一行的baseline來擺放

若是想改變對齊方式怎麼辦呢?

6.4 vertical-align 垂直對齊關係

  • 定義盒子所處的行盒(line box)的垂直對齊關係
  • 取值:baseline | sub | super | top | text-top | middle | bottom | text-bottom | <percentage>| <length>
  • 百分比相對於元素自身的行高
  • 初始值 baseline

img

由上圖舉例說明:

  1. 首先給這些元素畫一個baseline(基線),baseline的肯定是按照父級盒子的字體的大小來肯定的。
  2. 若是給文字設置成vertical-alignmiddle,middle這根線的位置是x-height的一半(x-height在font-metrics圖片中有定義)。
  3. 若是行盒Text設置成vertical-align設置爲text-top,那麼它的上邊緣與text-top這條線對齊。
  4. 其餘同理。

6.5 舉個栗子🌰

<p>
  <img 
    src="https://p5.ssl.qhimg.com/t013753a42172e3170a.jpg"
    alt="car"
    width="400"
  />
</p>

<style>
  p {
    padding: 0;
    background: red;
  }
</style>

代碼演示:

img

能夠看出img圖片是基於p標籤中的文字基線來排版的,那麼如何讓圖片下面這段紅線去掉呢?

  1. 能夠將img設置成block,這樣塊級與塊級就不會涉及(行內排版)這種狀況。
  2. 能夠給p設置vertical-align設置middle屬性,這樣img的中線與p的中線對齊,就不會出現這種問題

7、水平方向的對齊方式

  • text-align
  • 定義文本在容器內的對齊方式
  • 取值:left | right | center | justify(兩端對齊)
  • 初始值由 HTML 的 dir 屬性決定,可繼承

7.1 看一下這坨代碼中text-align: justify生效了麼?

<nav>
  <a href="#">Home</a>
  <a href="#">Products</a>
  <a href="#">Contact</a>
  <a href="#">Help</a>
</nav>

<style>
nav {
  text-align: justify;
  background: #dcc
}
nav a {
  display: inline-block;
  line-height: 3;
}
</style>

img

答案是並無,這是由於什麼呢?由於nav中的文字僅僅只有一行,它是第一行也是最後一行,text-align:justify不會對最後一行起做用。

img

css爲何要這樣設置呢?

咱們能夠想一下,若是咱們有多行文字,最後結尾的文字大多數都是少於一行的,若是css對於最後一行文字也進行兩端對齊的話,豈不是很醜。。。

像這樣:
img

因此css不給最後一行文字進行兩段對齊。

7.2 若是咱們要強制讓最後一行兩端對齊呢?

可使用text-align-last:justify, 能夠給最後一行文字設置兩端對齊。

8、最後

若是對你有所幫助,請點個贊呀~~

若是想對css想深刻了解能夠看看張鑫旭老師的博客,關注奇舞週刊~

相關文章
相關標籤/搜索