年初,公司 UI 框架升級,幾番比較以後,layui 和 adminLte 同時入選。當然,很明顯,這倆框架都是師出 bootstrap,提供基礎的樣式、組件、插件。但要‘本土化’到項目中來,多少要再翻炒一遍。公司的系統頁,大多基於頁面高寬100%來開發作業,以前的佈局框架,無論是自己寫的,還是插件,如ui-layout,都是用腳本計算。
現在,這倆新框架,柵格部分勉強算佈局的話,那就是他們的極限了,像例1這種簡單佈局,各個區域彈性佈局,中間區域超出滾動,翻遍這兩位文檔,都毫無建樹!
如果更復雜點,分上下左右中五塊,在各區域內再上下左右佈局,那你不得瘋掉!
例1:
可其實一想,自Css3出來後,這種用樣式都能解決的事,還引用插件,本身就反社會!用插件來佈局的時候,還要考慮加載數據和佈局腳本先後順序、頁面數據插入更新影響佈局等。
以前,大家都諾基亞用慣了,怕iphone(css3)是新生事物,有兼容問題,現在連買菜的師奶都用iphone (Css3)了,自然是再普通不過。
對 ui-layout 有了解的都應該知道,ui-layout 一個能實現各區域的彈性佈局,其二是間隔條帶有切換開關(可設置各區默認顯示隱藏:如例2)。根據這兩條,我們試試用純 Css 做一個!
例2:
1,實現上下左右中佈局
測試中,上、下、左右、中分別對應div:header、footer、side、center
這個比較簡單,如下面代碼,但需留意 flex 這兩點:
1)、flex 子元素高寬塌陷,可參考 《Flex 子元素高度塌陷》
2)、像 .main這樣的佈局元素,無法設置高度,.main 加上 display:flex 再佈局,子元素 高度 100% 無效。
3)、flex 垂直佈局,IE失效,需要在 flex-grow:1 的子元素上,加 -ms-flex: 1 解決兼容!(不是 -ms-flex-grow)
例3:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>flex</title>
<style>
html{ height: 100%; }
body,.layout{ display: flex; flex-direction: column;margin:0; height:100%; background: #fff; }
.header{ height: 24px; line-height:24px; font-size: 14px; color: #333; background: #fff; border-bottom: 1px solid #11a3ee; }
.main{ -ms-flex: 1; flex-grow: 1; display: flex; }
.side,.header,.footer{padding: 10px; flex-shrink:0; }
.side{ min-width: 200px; max-width: 40%;}
.gap{ position: relative; width: 5px; cursor:pointer; margin: 0;background:#ddd; border-left: 1px solid #bbb; border-right: 1px solid #bbb; }
.center{flex-grow: 1; overflow:auto; }
.footer{ background:#e2e2e2; }
</style>
</head>
<body>
<div class="header">標題</div>
<div class="main">
<div class="side">west side</div>
<div class="gap"></div>
<div class="center"><div style="height: 800px;">center</div></div>
<div class="gap"></div>
<div class="side">east side</div>
</div>
<div class="footer">Copyright ©2018 Marc</div>
</body>
</html>
2、點擊間隔條,顯示隱藏相關區域
純css的切換,可能你馬上想到純Css選項卡:利用 錨點、label + radio,道理差不多,但這裏都用不到,而且個人希望.gap只能是一個標籤,加一堆標籤,開發上哪海底撈去。
這裏要考慮兩個問題:
1)、.gap 怎樣做成一個切換按鈕?
2)、代碼,.gap只能放切換side前(例4),但頁面呈現,又必須在side後。
.gap:checked + .side{ display: none }
gap:checked + side,因爲相鄰選擇器只能選擇後面的元素
例 4:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>flex</title>
<style>
html{ height: 100%; }
body,.layout{ display: flex; flex-direction: column;margin:0; height:100%; background: #fff; }
.header{ height: 24px; line-height:24px; font-size: 14px; color: #333; background: #fff; border-bottom: 1px solid #11a3ee; }
.main{ -ms-flex: 1; flex-grow: 1; display: flex; }
.side,.header,.footer{ padding: 10px; flex-shrink:0; }
.side{ min-width: 200px; max-width: 40%;}
.gap{ position: relative; width: 5px; cursor:pointer; margin: 0; background:#ddd; border-left: 1px solid #bbb; border-right: 1px solid #bbb; }
.center{ flex-grow: 1; overflow:auto; }
.footer{ background:#e2e2e2; }
</style>
</head>
<body>
<div class="header">標題</div>
<div class="main">
<div class="gap"></div>
<div class="side">west side</div>
<div class="center"><div style="height: 800px;">center</div></div>
<div class="gap"></div>
<div class="side">east side</div>
</div>
<div class="footer">Copyright ©2018 Marc</div>
</body>
</html>
.gap 做成一個切換,這個問題困擾我很久,翻來覆去,發現能用的、最合適的也就 checkbox 了,能切換、又能默認設置關閉隱藏,如例5:成功切換 side!
例5:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>flex</title>
<style>
html{ height: 100%; }
body,.layout{ display: flex; flex-direction: column;margin:0; height:100%; background: #fff; }
.header{ height: 24px; line-height:24px; font-size: 14px; color: #333; background: #fff; border-bottom: 1px solid #11a3ee; }
.main{ -ms-flex: 1; flex-grow: 1; display: flex; }
.side,.header,.footer{padding: 10px; flex-shrink:0; }
.side{ min-width: 200px; max-width: 40%;}
.gap{ cursor:pointer; margin: 0; }
.gap:checked + .side{ display: none; }
.center{ flex-grow: 1; overflow:auto; }
.footer{ background:#e2e2e2;}
</style>
</head>
<body>
<div class="header">標題</div>
<div class="main">
<input type="checkbox" class="gap" title="切換" />
<div class="side">west side</div>
<div class="center"><div style="height: 800px;">center</div></div>
<input type="checkbox" class="gap" title="切換" />
<div class="side">east side</div>
</div>
<div class="footer">Copyright ©2018 Marc</div>
</body>
</html>
不用管checkbox 大小,先解決問題2:左邊區域的 gap 跑到 side 前面了,但頁面裏,gap 需要顯示 在 side 後面,怎麼辦?
也就是排序問題,如果仔細研究過 flex,你應該知道 flex 有個屬性 叫 order,沒錯,用 order 來排序!試一試!
柳暗花明,最黑暗處照進一道光,如此,美妙!
例6:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>flex</title>
<style>
html{ height: 100%; }
body,.layout{ display: flex; flex-direction: column; margin:0; height:100%; background: #fff; }
.header{ height: 24px; line-height:24px; font-size: 14px; color: #333; background: #fff; border-bottom: 1px solid #11a3ee; }
.main{ -ms-flex: 1; flex-grow: 1; display: flex; }
.side,.header,.footer{ padding: 10px; flex-shrink:0; }
.side{ min-width: 200px; max-width: 40%;}
.gap{ cursor:pointer; margin: 0; }
.gap:checked + .side{ display: none;}
.center{ flex-grow: 1; overflow:auto; }
.footer{ background:#e2e2e2;}
.main>.side:nth-of-type(1){ order:1; }
.main>.gap:nth-child(1){ order:2;}
.center,.center+.gap,.center+.gap+.side{ order:3; }
</style>
</head>
<body>
<div class="header">標題</div>
<div class="main">
<input type="checkbox" class="gap" title="切換" />
<div class="side">west side</div>
<div class="center"><div style="height: 800px;">center</div></div>
<input type="checkbox" class="gap" title="切換" />
<div class="side">east side</div>
</div>
<div class="footer">Copyright ©2018 Marc</div>
</body>
</html>
最後,checkbox大小的問題!
只有花生米大小,高寬又無法更改(千萬別出加:zoom 或 transform:scale(1w)這種餿主意),讓我曾反反覆覆多次放棄 checkbox,去需求其他出口,未果,只好硬着頭皮回來,地毯式搜索一個個屬性嘗試!因爲要滿足以下三個條件:
1)、只能在 gap 內加標籤,最好只有 gap 一個標籤!不接受外面再加標籤: label
<label for="side"></label>
<input type="radio" id="side" class="gap">
<div class="side"></lable>
2)、gap 要實現高100%,但又不能影響功能實現
<label for="side" class="gap"><input type="radio" id="side"></label>
<div class="side"></lable>
3)、.main 由於沒有設置高度,子元素在 不脫離文檔流(position:static、position:relative) 的情況下100% 無效,絕對定位,100%有效,但 gap 定位的top、left 都不確定!
最後嘗試到一個神奇的方法,要實現這個方法,先實現 gap 高100% :main內加了個高100%的標籤(wrap)
這個神奇的方法呢,就是僞類!給 gap 加僞類,用僞類的100%高做門面。神奇的是,點擊僞類層 ,checkbox 切換一樣絲般順滑!有意思!
例7:IE支持10及以上版本
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>flex</title>
<style>
html{ height: 100%; }
body,.layout{ display: flex; flex-direction: column;margin:0; height:100%; background: #fff; }
.header{ height: 24px; line-height:24px; font-size: 14px; color: #333; background: #fff; border-bottom: 1px solid #11a3ee; }
.main{ -ms-flex: 1; flex-grow: 1; position: relative; }
.wrap{ position:absolute; display: flex; width: 100%; height: 100%; }
.side,.header,.footer{padding: 10px; flex-shrink:0; }
.side{ min-width: 200px; max-width: 40%;}
.gap{ position: relative;box-sizing: border-box;margin: 0;width: 10px;height: 100%;background: #ddd;border-left: 1px solid #bbb;border-right: 1px solid #bbb;cursor:pointer; }
.gap:after{ position: absolute; top:0; right: 0; left: 0; bottom:0; content: ""; background: #ddd; border-left: 1px solid #bbb; border-right:1px solid #bbb; }
.gap:checked + .side{ display: none; }
.center{ flex-grow:1; overflow:auto; }
.footer{ background:#e2e2e2; }
.wrap>.side:nth-of-type(1){order:1; }
.wrap>.gap:nth-child(1){ order:2; }
.center,.center+.gap,.center+.gap+.side{order:3; }
</style>
</head>
<body>
<div class="header">標題</div>
<div class="main">
<div class="wrap">
<input type="checkbox" class="gap" title="切換" />
<div class="side">west side</div>
<div class="center"><div style="height: 800px;">center</div></div>
<input type="checkbox" class="gap" title="切換" checked="checked" />
<div class="side">east side</div>
</div>
</div>
<div class="footer">Copyright ©2018 Marc</div>
</body>
</html>
到此,順利實現了!說的有些囉嗦了!我在公司項目中,暫時只用佈局部分。
最後,留個問題,input來做切換、多加的那層wrap標籤,是否可以再優化呢!希望你有更好的方法!