在實際開發的過程當中,內容溢出是常常見到的。若是不深刻了解這個機制,你常常會碰到這樣的問題:爲何這個元素沒有受到祖先元素的overflow:hidden的影響?這裏出現的滾動條是哪一個元素的?如何消除這個滾動條?如何在指定的元素上增長滾動功能?
在這篇文章,咱們將會從CSS標準出發,討論CSS溢出機制的細節。css
當一個盒子(block container box)的內容(子元素、孫子元素等後裔)超過盒子自己的大小的時候,就會出現溢出。這個時候CSS屬性overflow決定如何處理溢出。這個css屬性你們都知道,在這裏不討論了,在這裏指出須要注意的幾點:html
<A><B><C><C/><B/><A/>
,通常來講,B的overflow會影響C,可是若是C是相對於viewport或者A定位的(好比使用了position:absolute),那麼C的顯示就不受B的裁剪、滾動的影響。overflow
屬性是從<html>或者<body>元素竊取來的:若是<html>的overflow
不是'visible'(默認值),那就從<html>竊取;不然,從<body>竊取。若是viewport竊取來的overflow
是'visible',那麼將它視爲'auto'(由於不可能在viewport以外顯示內容)。被竊取的元素,它的overflow
被設置爲'visible'。能夠推斷出:chrome
通常來講只有元素才能擁有滾動條(更準確地說,只有產生block container box的元素才能擁有滾動條)。但visual viewport是個例外。它雖然不是一個元素,可是也能夠擁有滾動條。若是在<html>和<body>上都沒有設置overflow屬性而使用默認值visible(大部分場景都是這樣),那麼,visual viewport的overflow就是auto:當網頁中有內容超出visual viewport時,visual viewport上會出現滾動條。canvas
關於viewport的討論在 【響應式佈局】initial containing block、viewport以及相關尺寸。
小練習:利用以上原理,使visual viewport和<body>都擁有橫、豎滾動條,總共4個滾動條。不能使用overflow: scroll(這樣就太簡單了)。
步驟:segmentfault
代碼+註釋:瀏覽器
<!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>
結果:
app
本身在chrome中打開以上代碼,能更加清晰地看出是怎麼作到的。
也能夠經過absolute的方式來溢出initial containing block:佈局
<!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中打開以上代碼,能更加清晰地看出是怎麼作到的。
經過Chrome DevTools就能夠看出滾動條的所屬元素。
前面已經說過,滾動條的位置在元素的border與padding之間。當你使用Chrome DevTools選中某個元素,發現滾動條剛好在高亮區域(border)內部時,滾動條就屬於當前元素。
spa
要判斷滾動條是否屬於visual viewport,首先先將右邊、下邊的滾動條分別滾動到最下、最右(這一步很重要,它保證沒有內容藏在滾動條下面)。而後,Ctrl+Shift+C
選擇右邊或下邊的滾動條,若是高亮的區域不包含這個滾動條,就說明這個滾動條不屬於任何元素,也就是屬於visual viewport。
https://developer.mozilla.org...
https://developer.mozilla.org...
獲取或設置元素的內容被滾動的距離。這兩個屬性適用於全部Element。
若是想要獲取visual viewport的滾動距離,除了這個方法之外,還有更多等效的方法。見【響應式佈局】initial containing block、viewport以及相關尺寸。