跳到主要內容

HTML, CSS, 相對視窗或螢幕的高度與寬度

w3school.com網站,CSS Units有各種與寬度的表示法

以我使用的頻率來排序:

  • px: 使用螢幕幾個像素(但是還要考慮Retina螢幕像素是一般螢幕像素的兩倍)
  • %: 相對父層的大小比例
  • vh, vw: 相對於瀏覽器展示網頁區域的大小(不是整個瀏覽器的大小,沒包含瀏覽器的工具列,只有展示網頁的區域)
  • vmin: vh, vw取最小值(另外還有vmax則是取最大值,但是目前IE跟safari不支援)

px%很常用,vhvwvmin是CSS3的新產物,表示相對瀏覽器展示頁面的大小


相對視窗大小

這邊先說明,vhvwvmin只包含網頁顯示區域的長寬,不包含瀏覽器的工具列

先從dom的最根本講起好了,一份HTML文件,根是<html></html>(雖然沒有嚴格規定,不寫也能顯示),然後這個根的父元件就是瀏覽器的網頁頁面顯示區

因此,如果對<html></html>宣告大小是100%就跟宣告100vh一樣,因為都是指瀏覽器的網頁頁面顯示區大小

這個範例是將html設定為100vh

<html style="height: 100vh">
    <head>
        <script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>

        <script type="text/javascript">
            console.log($('html').height());
        </script>
    </head>
</html>

這個範例是將html設定為100%

<html style="height: 100%">
    <head>
        <script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>

        <script type="text/javascript">
            console.log($('html').height());
        </script>
    </head>
</html>

這兩者在瀏覽器的console應該輸出一樣的大小

如果從html, body到div , 這些tag都填入100%,則從頭到尾都填滿整個視窗(當然還注意body預設有padding, margin佔有一些寬度,要把他們都設為0,才會真的佔滿全畫面)

不過現在有vh, vw,就不用這麼麻煩了,可以只設定長度為100vh, 寬度為100vw,就可以填滿整個畫面(依然得注意body預設佔有padding跟margin)

像下面這樣就能把兩個div排在一起,並且以瀏覽器寬度3:7的比例,分割成兩個區塊

<html>
    <head></head>
    <body style="margin: 0;padding: 0;">
        <div style="width: 30vw;float:left;">Left...</div>
        <div style="width: 70vw;float:left;">Right...</div>
    </body>
</html>

還有一個問題,以往使用桌上型電腦的螢幕,我們可以預期大部分人的電腦,都是寬度大於長度,大部份的人也都是用全螢幕瀏覽網頁。所以我們很信任的將長寬都設定成vh就可以變成正方形,並且不超過瀏覽器大小。

但是現在手機螢幕,可以拿直的,也可以拿橫的,那要怎麼辦呢?就使用vmin

譬如我們要顯示一張正方形的圖片,希望以最大張的方式呈現

<html>
    <head></head>
    <body style="margin: 0;padding: 0;">
        <img src="圖片路徑" style="width: 100vmin;height: 100vmin;">
    </body>
</html>

這樣就不怕桌機或手機,螢幕擺直得或橫的,都以最大張,且不會超出瀏覽器範圍欄顯示圖片


相對螢幕大小

那可不可以相對於使用者整個螢幕的大小?

可以,但是要使用Javascript去設定,在Javascript裡面直接使用screen.heightscreen.width,就可以取得螢幕大小(關於screen是什麼?請參考w3school的相關頁面)

之後再用dom語法,去改你要改的地方,假設你要將所有的div tag寬度都隨使用者螢幕寬度改變,這邊使用jQuery:

$('div').width(screen.width);

這時候不管使用者怎麼拉動瀏覽器的寬度,所有的div tag寬度都等是螢幕寬度

如果想單純使用javascipt的話,語法比較冗長一點,可以參考w3chool的頁面,注意他傳入的參數後面還要接單位,所以在screen.width之後記得再加上"px",之後才當引數傳進去

回到原本的jQuery版本,如果想要75%的螢幕大小

$('div').width(screen.width * 0.75);

想要30%的螢幕大小

$('div').width(screen.width * 0.3);

以此類推,我一開始會害怕對screen.width做數學運算,因為不確定內容是字串還是數字。但是多慮了,javascript可以對數字做數學運算,也可以對內容是數字的字串做數學運算

'10' * '10' // 輸出100
'10' * 10 // 也輸出100

如果是在Ruby,則是輸出"10101010101010101010",所以在javascript裡面,不用怕,他內容是數字,就直接對他做數學運算,不用先檢查型別。(若字串內容不是數字,會輸出NaN,Not a Number的意思)

留言

這個網誌中的熱門文章

陣列洗牌程式(shuffle array)

陣列如何把它的順序打亂,作出類似洗牌的效果,我一直都很頭痛,搞得非常的複雜。至從用了Ruby,Array物件包含 shuffle 方法之後,我就沒思考過陣列洗牌的問題了,反正Ruby幫我處理得好好的。 Ruby # 52張牌的牌堆 poker = (1..52).to_a # => [1, 2, 3, ... , 52] # 洗牌打亂 shuffled = poker.shuffle # => [22, 32, 12, ... # 也可以直接打亂原來的陣列 poker.shuffle! # => [39, 47, 3, ... Javascript Javascript我就頭痛了,我得自己寫洗牌的方法。我在網路上找到了這個演算法,仔細看了之後,才知道原來洗牌可以這麼簡單: // 原本for迴圈是一行程式,太難理解,這邊改寫成多行 function shuffle(o){ for(var j, x, i = o.length; i;){ j = Math.floor(Math.random() * i); // javascript的array是0-base // 所以迴圈第一次進入,--i後表示陣列最後一個位置。 x = o[--i]; o[i] = o[j]; o[j] = x; // 以上三行代表以x為temp, o[i], o[j]做交換 } return o; //回傳陣列,我一開始也看錯看成回傳0 }; 變數說明 引數o: 將被洗牌的陣列 for迴圈內 i : 將會從陣列的最後一個位置,慢慢往前移到第一個位置(但移到第一個位置時for迴圈不執行,因為Javascript的數值0也代表false,會離開迴圈。0代表flase這點跟Ruby不一樣) j : 將會被亂數選擇,選到要被交換的位置 x : 用來暫存o[i]的數值,幫助o[i]與o[j]做數值交換 就這樣從最後一個位置開始,依次往前隨機挑選一個位置與它交換(可能挑到自己,表示不交換),來達到洗牌的效果,陣列多大,就執行幾次,時間複雜度 O(n) ,...

linux, bash, find 的應用(-exec, sed -i, 檔案內取代, 與xargs比較)

find -exec find -exec 指的是將找到的檔案,送到後面的指令去處理。從 -exec 到 \; 為止,代表是接受從find送來要處理的指令,而送來的檔案將用 {} 代表找到的檔案。 譬如你想把所有副檔名為 .log 的檔案刪除掉,可以這麼做 find . -type f -name "*.log" -exec rm {} \; (其實我加上 -type f 有點多餘,因為我已經指定 -name "*.log" 了,就不可能輸出資料夾了。) 如果刪檔案的時候,一直要你按 yes ,可以這樣 yes | find . -type f -name "*.log" -exec rm {} \; yes 這個指令會一直串流輸出yes,這樣刪檔案就自動一直輸入yes 例子中 find 找到的檔案,就放到 -exec 至 \; 之間的指令去處理,譬如找到了檔案 develop.log ,就會變成 rm develop.log 另外, {} 並不是規定只能出現一次,譬如你要將資料夾內所有檔案加上副檔名 log ,可以這麼做 find . -type f -exec mv {} {}.log \; 這指令會包含子資料前內的檔案都加上.log副檔名。如果只想要目前資料夾的檔案,所以可以加上 -maxdepth 1 ,若要地回到下一層資料夾可以將1改成2,3或4以此類推 find . -maxdepth 1 -type f -exec mv {} {}.log \; 因此,若要批次改變檔案的內容,就可以搭配 find -exec 跟 sed -i 。sed 加上 -i 參數,代表直接對檔案內容做修改。 我常常在幫別人複製或移動網站,很多人的網址都寫成包含域名的絕對路徑,所以常常要用這個指令去找出所有含舊域名的檔案,並改成新域名。 譬如舊域名為 http://www.old.com ,要改成 http://www.new.com ,我會這麼做 find . -type f -exec sed -i 's/www.old.com/www.new.com/g' {} \; (sed這個指令在OS X上面如果照上例那樣執行,會有...