本身動手實現一個 Flex 佈局框架

圖片描述

本文做爲 Flex 佈局進階,不對基礎作詳細介紹,關於 Flex 基礎知識請到阮一峯老師的Flex 佈局教程:語法篇css

看過基礎,或者已經使用 Flex 佈局的朋友能夠根據本文試着動手寫一寫,先不急着開工,看看其它大型框架怎麼實現的。html

Bootstrap 框架

相信你們都用過 Bootstrap 框架,目前最受歡迎的響應式佈局框架,在 Github 上 10w+ 的 starangularjs

而其中的柵格系統深刻人心,針對不一樣尺寸的屏幕提供一套完整佈局方案,不瞭解柵格系統的能夠看中文官方文檔柵格系統設計模式

對於新人概念有點多,跳躍性挺強,不過跟着跳轉連接一步一步摸索很快就能入門,這裏給的都是中文連接。框架

給出一段柵格系統的代碼片斷ide

<div class="row">
  <div class="col-md-1">.col-md-1</div>
  <div class="col-md-1">.col-md-1</div>
  <div class="col-md-1">.col-md-1</div>
  <div class="col-md-1">.col-md-1</div>
  <div class="col-md-1">.col-md-1</div>
  <div class="col-md-1">.col-md-1</div>
  <div class="col-md-1">.col-md-1</div>
  <div class="col-md-1">.col-md-1</div>
  <div class="col-md-1">.col-md-1</div>
  <div class="col-md-1">.col-md-1</div>
  <div class="col-md-1">.col-md-1</div>
  <div class="col-md-1">.col-md-1</div>
</div>
<div class="row">
  <div class="col-md-8">.col-md-8</div>
  <div class="col-md-4">.col-md-4</div>
</div>
<div class="row">
  <div class="col-md-4">.col-md-4</div>
  <div class="col-md-4">.col-md-4</div>
  <div class="col-md-4">.col-md-4</div>
</div>
<div class="row">
  <div class="col-md-6">.col-md-6</div>
  <div class="col-md-6">.col-md-6</div>
</div>

效果以下模塊化

圖片描述

這裏柵格系統將屏幕水平均分紅 12 份。經過加對應的 class 調整佈局。語法也通俗易懂不過多解釋。佈局

再來看另外一個列偏移的例子學習

<div class="row">
  <div class="col-md-4">.col-md-4</div>
  <div class="col-md-4 col-md-offset-4">.col-md-4 .col-md-offset-4</div>
</div>
<div class="row">
  <div class="col-md-3 col-md-offset-3">.col-md-3 .col-md-offset-3</div>
  <div class="col-md-3 col-md-offset-3">.col-md-3 .col-md-offset-3</div>
</div>
<div class="row">
  <div class="col-md-6 col-md-offset-3">.col-md-6 .col-md-offset-3</div>
</div>

效果以下flex

圖片描述

使用 .col-md-offset-* 類能夠將列向右側偏移。這些類實際是經過使用 * 選擇器爲當前元素增長了左側的邊距(margin)。例如,.col-md-offset-4 類將 .col-md-4 元素向右側偏移了4個列(column)的寬度。

看到這裏你們感受這個方案很完美,既有相應佈局又有佈局的偏移,但個人項目需求是這樣的

圖片描述

這裏單選按鈕和票的名稱居左,而票價居右,左右給相同的 padding 後,單選按鈕和票價分別在左右處於臨界狀態,我並不知道右側的票價佔幾個柵格,也不知道左側的偏移到底給多少合適(由於票價是變量,可能 10 位數,固然可能性爲 0)

瞭解 flex 基礎的一眼識破,不是有 space-between 嘛,對就是它,不瞭解的朋友繼續轉到文章開頭的連接溫習一下。

下文咱們去找設計靈感

Angular Material 框架

What is Angular Material?

For developers using AngularJS, Angular Material is both a UI Component framework and a reference implementation of Google's Material Design Specification. This project provides a set of reusable, well-tested, and accessible UI components based on Material Design.

用過 AngularJS 的人應該多少有所耳聞,沒據說的也不要緊。咱們學習的是設計思想而不是研討一門框架。

這裏的案例來源於:https://material.angularjs.or...

上面連接是 Angular Material 框架佈局部分的 API 文檔,文檔下方有單選按鈕組合來呈現不一樣的佈局實現。

先給出基本代碼

<div layout="row" layout-align="center center">
  <div>one</div>
  <div>two</div>
  <div>three</div>
</div>

效果以下

圖片描述

其它屬性以下,

圖片描述

進入上方連接能夠在線感覺一下,全部佈局效果,這裏不一一截圖

一樣也支持柵格系統不過這裏更精密一些,是 100 份的均分,官網例子給的特別全面,連接: https://material.angularjs.or...

這裏給你們選出一個比較通用的例子,代碼以下

<div layout="row" layout-wrap>
  <div flex="30">
    [flex="30"]
  </div>
  <div flex="45">
    [flex="45"]
  </div>
  <div flex="25">
    [flex="25"]
  </div>
  <div flex="33">
    [flex="33"]
  </div>
  <div flex="66">
    [flex="66"]
  </div>
  <div flex="50">
    [flex="50"]
  </div>
  <div flex>
    [flex]
  </div>
</div>

效果以下

圖片描述

代碼簡潔易懂,layout="row"表示在水平方向分佈,最後的 flex 不帶參數代表自動填充,將不帶 flex 屬性的元素以前的空間填滿。

下面咱們回到需求,針對需求給出 html 結構的設想

<div layout="row">
  <div flex>單選按鈕和票的名稱</div>
  <div>票價</div>
</div>

或者乾脆

<div layout="row" layout-align="space-between center">
  <div>單選按鈕和票的名稱</div>
  <div>票價</div>
</div>

好,有的朋友說使用 float 或者 text-align 也能夠知足需求的啊,幹嗎寫這麼長篇幅的文章解釋這個案例?

問的好,首先 flex 佈局優點特別明顯,彈性佈局,不存在兼容問題,也不用清除浮動。

設想一下項目複雜度再大一點呢,守舊的方案還能不能保持清晰的 html 文檔結構?css 又該從哪裏下手?

既然咱們出發點是對的,接下來選擇一下設計模式。

簡單說兩種模式

  • class 屬性爲表明的 Bootstrap 框架
  • 自定義屬性爲表明的 Angular Material 框架

我我的認爲 class 過多致使佈局和樣式混在一塊兒很差分辨,後期維護較困難,決定採用 Angular Material 框架的設計模式。

首先你們要了解 css 屬性選擇器,經常使用的有 class選擇器,id選擇器,tag選擇器,屬性選擇器仍是比較少用的。

下面給 w3school 的截圖,子串匹配屬性選擇器的語法

圖片描述

簡單易懂,下面直接上寫好的代碼 layout.scss

[layout] {
  display: flex;
}

[flex] {
  flex: 1;
}

[layout-wrap] {
  flex-wrap: wrap;
}

[layout="row"] {
  flex-direction: row;
}

[layout-wrap] {
  flex-wrap: wrap;
}

[layout="column"] {
  flex-direction: column;
}

[layout-align="start start"],
[layout-align="start center"],
[layout-align="start end"] {
  justify-content: flex-start;
}

[layout-align="center start"],
[layout-align="center center"],
[layout-align="center end"] {
  justify-content: center;
}

[layout-align="end start"],
[layout-align="end center"],
[layout-align="end end"] {
  justify-content: flex-end;
}

[layout-align="space-between start"],
[layout-align="space-between center"],
[layout-align="space-between end"] {
  justify-content: space-between;
}

[layout-align="space-arround start"],
[layout-align="space-arround center"],
[layout-align="space-arround end"] {
  justify-content: space-arround;
}

[layout-align="start start"],
[layout-align="center start"],
[layout-align="end start"],
[layout-align="space-between start"],
[layout-align="space-arround start"] {
  align-items: flex-start;
}

[layout-align="start center"],
[layout-align="center center"],
[layout-align="end center"],
[layout-align="space-between center"],
[layout-align="space-arround center"] {
  align-items: center;
}

[layout-align="start end"],
[layout-align="center end"],
[layout-align="end end"],
[layout-align="space-between end"],
[layout-align="space-arround end"] {
  align-items: flex-end;
}

好,到這爲止咱們的 flex 框架已經實現了,效果語法和 Angular Material 框架是同樣的。你們自行嘗試。

細心的朋友發現這裏 orange 並無實現柵格系統,由於現實需求中柵格系統佈局的實用價值不是很大(各元素寬度根據內容變化,手機端在元素寬度不變的狀況能夠經過相同的 rem 值針對不一樣屏幕適配,而 n 等分能夠經過 space-arround 屬性實現),並且本文把開發的重點放在了 flex 的封裝上。

總結

在現代複雜 css 樣式的開發中,儘可能避免重複書寫相同的佈局代碼,除非特殊需求(真對相應的 class 給樣式),這樣既知足模塊化思想又保證了代碼複用,項目中只需引入 layout.scss 便可。若是你針對 css 代碼模塊化有不一樣的想法歡迎留言交流。

文章出自 orange 的 我的博客 http://orangexc.xyz/
相關文章
相關標籤/搜索