未加星标

自己动手实现一个 Flex 布局框架

字体大小 | |
[前端(javascript) 所属分类 前端(javascript) | 发布者 店小二04 | 时间 2016 | 作者 红领巾 ] 0人收藏点击收藏

自己动手实现一个 Flex 布局框架

本文作为 Flex 布局进阶,不对基础做详细介绍,关于 Flex 基础知识请到阮一峰老师的 Flex 布局教程:语法篇

看过基础,或者已经使用 Flex 布局的朋友可以根据本文试着动手写一写,先不急着开工,看看其它大型框架怎么实现的。

Bootstrap 框架

相信大家都用过 Bootstrap 框架,目前最受欢迎的响应式布局框架,在 Github 上 10w+ 的 star

而其中的栅格系统深入人心,针对不同尺寸的屏幕提供一套完整布局方案,不了解栅格系统的可以看 中文官方文档栅格系统

对于新人概念有点多,跳跃性挺强,不过跟着跳转链接一步一步摸索很快就能入门,这里给的都是中文链接。

给出一段栅格系统的代码片段

<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>

效果如下


自己动手实现一个 Flex 布局框架

这里栅格系统将屏幕水平均分成 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)的宽度。

看到这里大家感觉这个方案很完美,既有相应布局又有布局的偏移,但我的项目需求是这样的


自己动手实现一个 Flex 布局框架

这里单选按钮和票的名称居左,而票价居右,左右给相同的 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.org/1.0.8/layout/alignment

上面链接是 Angular Material 框架布局部分的 API 文档,文档下方有单选按钮组合来呈现不同的布局实现。

先给出基本代码

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

效果如下


自己动手实现一个 Flex 布局框架

其它属性如下,


自己动手实现一个 Flex 布局框架

进入上方链接可以在线感受一下,所有布局效果,这里不一一截图

同样也支持栅格系统不过这里更精密一些,是 100 份的均分,官网例子给的特别全面,链接: https://material.angularjs.org/1.0.8/layout/children

这里给大家选出一个比较通用的例子,代码如下

<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>

效果如下


自己动手实现一个 Flex 布局框架

代码简洁易懂, 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 的截图,子串匹配属性选择器的语法


自己动手实现一个 Flex 布局框架

简单易懂,下面直接上写好的代码 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 的封装上。

本文前端(javascript)相关术语:javascript是什么意思 javascript下载 javascript权威指南 javascript基础教程 javascript 正则表达式 javascript设计模式 javascript高级程序设计 精通javascript javascript教程

分页:12
转载请注明
本文标题:自己动手实现一个 Flex 布局框架
本站链接:http://www.codesec.net/view/482657.html
分享请点击:


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 前端(javascript) | 评论(0) | 阅读(36)