1. 程式人生 > >csRyan的學習專欄

csRyan的學習專欄

當一個盒子的內容超過盒子本身的大小的時候,就會出現溢位。這個時候CSS屬性overflow決定如何處理溢位。這個css屬性大家都知道,在這裡不討論了,在這裡指出需要注意的幾點:

  • overflow會影響所在元素的所有內容的裁剪、滾動,但是有一種情況例外:"It affects the clipping of all of the element's content except any descendant elements (and their respective content and descendants) whose is the viewport or an ancestor of the element." 比如<A><B><C><C/><B/><A/>
    ,一般來說,B的overflow會影響C,但是如果C是相對於viewport或者A定位的(比如使用了position:absolute),那麼C的顯示就不受B的裁剪、滾動的影響。
  • 當需要滾動條的時候,滾動條會放在border與padding之間。父元素產生滾動條以後,它產生的containing block的尺寸會減少,以便給滾動條騰出空間。
  • 在<html>和<body>上的overflow屬性存在冒泡現象: "UAs must apply the 'overflow' property set on the root element to the viewport. When the root element is an HTML "HTML" element or an XHTML "html" element, and that element has an HTML "BODY" element
    or an XHTML "body" element as a child, user agents must instead apply the 'overflow' property from the first such child element to the viewport, if the value on the root element is 'visible'. The 'visible' value when used for the viewport must be interpreted as 'auto'. The element from which the value is propagated must have a used value for 'overflow' of 'visible'
    . "

可以推斷出:

  • 一般來說只有元素才能擁有滾動條,但visual viewport是個例外。它雖然不是一個元素,但是也可以擁有滾動條。如果在<html>和<body>上都沒有設定overflow屬性而使用預設值visible(大部分場景都是這樣),那麼,visual viewport的overflow就是auto:當網頁中有內容超出visual viewport時,visual viewport上會出現滾動條。
  • <html>的最終overflow永遠都是visible。也就是說,<html>元素永遠不可能擁有滾動條。
  • 如果你想要為<body>設定非visible的overflow,需要先為<html>設定一個非visible的值來冒泡,從而<body>的overflow不會被冒泡。

小練習:利用以上原理,使visual viewport和<body>都擁有橫、豎滾動條,總共4個滾動條。不能使用overflow: scroll(這樣就太簡單了)。步驟:

  1. 使visual viewport和<body>的最終overflow值都為auto,從而可以出現滾動條。
  2. 觸發visual viewport和<body>的溢位。通過【為內容設定一個更大的尺寸】來做到。

程式碼+註釋:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
  <title>test</title>
  <style>
    * {
      padding: 0;
      margin: 0;
      box-sizing: border-box;
    }

    html {
      /* 使html的尺寸始終與visual viewport相同(即使你縮放、調整瀏覽器視窗的大小),從而body可以設定一個比visual viewport還大的尺寸(110%)。
      對於預設為block的元素可以省略width: 100%; */
      width: 100%;
      height: 100%;
      /* 非visible的值冒泡到visual viewport上,使visual viewport可以出現滾動條 */
      overflow: auto;
      border: 15px solid red;
    }

    body {
      /* 使得body可以出現滾動條 */
      overflow: auto;
      /* body溢位html,從而溢位initial containning block,從而溢位visual viewport,使得visual viewport出現滾動條。
      當然,你也可以通過很多其他的方式來觸發visual viewport的溢位,比如增大html元素,或者在body中弄一個position: absolute的div */
      width: 110%;
      height: 110%;
      border: 15px solid green;
    }

    main {
      /* main溢位body,使得body出現滾動條 */
      width: 110%;
      height: 110%;
      border: 15px solid blue;
    }
  </style>
</head>

<body>
  <main>
  </main>
</body>

</html>

結果:

自己在chrome中開啟以上程式碼,能更加清晰地看出是怎麼做到的。
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
  <title>test</title>
  <style>
    * {
      padding: 0;
      margin: 0;
      box-sizing: border-box;
    }

    html {
      /* 使html的尺寸始終與visual viewport相同(即使你縮放、調整瀏覽器視窗的大小),從而body可以設定一個比visual viewport還大的尺寸(110%)。
      對於預設為block的元素可以省略width: 100%; */
      width: 100%;
      height: 100%;
      /* 非visible的值冒泡到visual viewport上,使visual viewport可以出現滾動條 */
      overflow: auto;
      border: 15px solid red;
    }

    body {
      /* 使得body可以出現滾動條 */
      overflow: auto;
      /* 為body設定一個尺寸,從而main可以設定一個比body還大的尺寸(110%)。
      對於預設為block的元素可以省略width: 100%; */
      height: 100%;
      border: 15px solid green;
    }

    main {
      /* main溢位body,使得body出現滾動條 */
      width: 110%;
      height: 110%;
      border: 15px solid blue;
    }

    .abs {
      /* 通過absolute的方式來溢位initial containing block,從而溢位viewport */
      position: absolute;
      width: 100px;
      height: 100px;
      right: -100px;
      bottom: -100px;
      border: 15px solid blueviolet;
    }
  </style>
</head>

<body>
  <main>
  </main>

  <div class="abs"></div>
</body>

</html>

結果:

自己在chrome中開啟以上程式碼,能更加清晰地看出是怎麼做到的。

參考資料