【React】【CSS】【案例】:Flex 弹性盒模型

您所在的位置:网站首页 css弹性盒模型 【React】【CSS】【案例】:Flex 弹性盒模型

【React】【CSS】【案例】:Flex 弹性盒模型

2024-01-27 20:35| 来源: 网络整理| 查看: 265

1. Flex 弹性盒模型

Flexible Box 模型,通常被称为 flexbox,是一种一维的布局模型。它给 flexbox 的子元素之间提供了强大的空间分布和对齐能力。

1.1. 知识体系总图

1.2. 浏览器兼容性

IE 是兼容性最棒的浏览器,没有之一 !

1.3. 主轴、垂轴、换行

当使用 flex 布局时,首先想到的是两根轴线 — 主轴和交叉轴。

主轴由 flex-direction 定义,另一根轴垂直于它。flexbox 的特性是沿着主轴或者交叉轴对齐之中的元素。flexbox 不会对文档的书写模式提供假设。

1.3.1. 主轴方向控制:flex-direction

flex-direction: row (主轴:左->右;垂轴:上->下) row-reverse (主轴:右->左;垂轴:上->下) column (主轴:上->下;垂轴:左->右) column-reverse(主轴:下->上;垂轴:左->右) 默认值:row;

示例:flex-direction 动画演示

1.3.2. 换行控制:flex-wrap

flex-wrap: nowrap(不换行) wrap(允许换行,新行沿垂轴堆叠) wrap-reverse(允许换行,并翻转垂轴方向,新行沿垂轴堆叠) 默认值:nowrap

示例:flex-wrap 动画演示

1.3.3. 主轴、垂轴方向总结

flex-flow: row wrap;

flex-flow: row-reverse wrap;

flex-flow: column wrap;

flex-flow: column-reverse wrap;

flex-flow: row wrap-reverse;

测试代码:

#flex-container{ color: #fff; font-size: 40px; text-align: center; } #flex-container{ display: flex; } 1 2 3 4 5 6 7 8 9 flex-direction: row row-reverse column column-reverse flex-wrap: nowrap wrap wrap-reverse function onFlexDirectionChange(){ var flexContainer = document.getElementById("flex-container"); var flexDirectionSelect = document.getElementById("flex-direction-select"); flexContainer.style.flexDirection = flexDirectionSelect.value; } function onFlexWrapChange(){ var flexContainer = document.getElementById("flex-container"); var flexDirectionSelect = document.getElementById("flex-wrap-select"); flexContainer.style.flexWrap = flexDirectionSelect.value; }

1.4. 主轴方向元素对齐

主轴方向是通过 flex-direction 设置的方向,justify-content 属性定义了如何分配顺着弹性容器主轴的元素之间及其周围的空间。

flex-start:从行首起始位置开始排列(默认值)flex-end:从行尾位置开始排列center:居中排列space-between:均匀排列每个元素首个元素放置于起点,末尾元素放置于终点space-around:均匀排列每个元素每个元素周围分配相同的空间

justify-content 主轴弹性元素对齐控制

1.5. 垂轴方向元素对齐

align-items 属性可以使元素在交叉轴方向对齐。

flex-start:元素向侧轴起点对齐。flex-end:元素向侧轴终点对齐center:元素在侧轴居中。baseline:所有元素向基线对齐。侧轴起点到元素基线距离最大的元素将会于侧轴起点对齐以确定基线。stretch:弹性元素被在侧轴方向被拉伸到与容器相同的高度或宽度。(默认值)

align-items 垂轴弹性元素对齐控制

1.6. 多条主轴的对齐

align-content 属性控制多条主轴在内容项之间和周围分配空间,该属性对单行弹性盒子模型无效。

flex-start:所有行从垂直轴起点开始填充。第一行的垂直轴起点边和容器的垂直轴起点边对齐。接下来的每一行紧跟前一行。flex-end:所有行从垂直轴末尾开始填充。最后一行的垂直轴终点和容器的垂直轴终点对齐。同时所有后续行与前一个对齐。center:所有行朝向容器的中心填充。每行互相紧挨,相对于容器居中对齐。容器的垂直轴起点边和第一行的距离相等于容器的垂直轴终点边和最后一行的距离。space-between:所有行在容器中平均分布。相邻两行间距相等。容器的垂直轴起点边和终点边分别与第一行和最后一行的边对齐。space-around:所有行在容器中平均分布,相邻两行间距相等。容器的垂直轴起点边和终点边分别与第一行和最后一行的距离是相邻两行间距的一半。stretch:拉伸所有行来填满剩余空间。剩余空间平均地分配给每一行。(默认值)

align-content 多主轴对齐控制

1.7. 视觉顺序控制

CSS order 属性规定了弹性容器中的可伸缩项目在布局时的顺序。元素按照 order 属性的值的增序进行布局。拥有相同 order 属性值的元素按照它们在源代码中出现的顺序进行布局。

order 弹性元素视觉顺序控制

1.8. flex-basis、flex-grow、flex-shrink 与 flex

flex-basis、flex-grow、flex-shrink 决定了弹性元素在弹性容器中的尺寸。

1.8.1. flex-basis

CSS 属性 flex-basis 指定了 flex 元素在主轴方向上的初始大小。

当一个元素同时被设置了 flex-basis (除值为 auto 外) 和 width (或者在 flex-direction: column 情况下设置了height) , flex-basis 具有更高的优先级.width 值可以是 ; 该值也可以是一个相对于其父弹性盒容器主轴尺寸的百分数 。负值是不被允许的。默认为 auto。不要单独使用 flex-basis 属性,应该统一使用属性 flex 控制。/* 指定 */ flex-basis: 10em; flex-basis: 3px; flex-basis: auto; // "flex-basis:auto" 的含义是 "参照我的width和height属性".

1.8.2. flex-grow、flex-shrink

CSS flex-grow 属性定义弹性盒子项(flex item)的拉伸因子。

负值无效

CSS flex-shrink 属性定义弹性盒子项(flex item)的收缩因子。

负值无效

拉伸、收缩关键算法:

拉伸示例:

.container { color: #fff; text-align: center; width: 900px; height: 100px; border:1px solid blue; } .container { display: flex; flex-direction: row; } 计算过程: 1. 剩余空间: 900px - 3*100px = 600px; 2. item1: 100 + 600 * (1 / (1+2+3)) = 200px 3. item2: 100 + 600 * (2 / (1+2+3)) = 300px 4. item3: 100 + 600 * (3 / (1+2+3)) = 400px 总结:按 flex-grow 的比例分配剩余空间

收缩示例:

.container { color: #fff; text-align: center; width: 900px; height: 100px; border:1px solid blue; } .container { display: flex; flex-direction: row; }

计算过程: 1. 过剩空间: (400px + 600px + 800px) - 900px = 900px; 2. item1: 400 - 900* (1*400 / (1*400 + 2*600 + 3*800)) = 310px 3. item2: 600 - 900 * (2*600 / (1*400 + 2*600 + 3*800)) = 330px 4. item3: 800 - 900 * (3*800 / (1*400 + 2*600 + 3*800)) = 260px 总结:按 (flex-shrink * flex-basis) 的比例分配剩余空间

1.8.3. flex

flex 是一个简写属性,用来设置 flex-grow, flex-shrink 与 flex-basis。

flex: ? ||

当使用一个或两个无单位数时, flex-basis会从auto变为0.

flex: auto; ==> flex: 1 1 auto; flex: none; ==> flex: 0 0 auto; flex: 1; ==> flex: 1 1 0; flex: 1 1; ==> flex: 1 1 0;

2. Flex 应用案例

2.1. 水平、垂直居中

.container { color: #fff; font-size: 40px; text-align: center; width: 600px; height: 400px; border:1px solid blue; } .container { display: flex; justify-content: center; align-items: center; } .item { width:200px; height: 200px; background-color: orange; } 4

2.2. 一侧固定、一侧自适应

html, body { width: 100%; height: 100%; } .container { color: #fff; text-align: center; width: 600px; height: 80%; border:1px solid blue; } .container { display: flex; flex-direction: column; } .item.fixed { flex: none; background-color: orange; } .item.fill{ flex: 1; overflow: auto; background-color: green; } 这里是固定高度区域,例如Banner 这里是内容区域

2.3. 圣杯布局

html, body { width: 100%; height: 100%; } .layout { color: #fff; text-align: center; width: 90%; height: 90%; border:1px solid blue; } .layout { display: flex; flex-direction: column; } .layout > .top, .layout > .bottom { background-color: blue; flex: none; } .layout > .middle { flex: 1; } .layout > .middle { display: flex; flex-direction: row; } .layout > .middle > .left, .layout > .middle > .right { background-color: green; flex: none; } .layout > .middle > .center { background-color: purple; flex: 1; } TOP LEFT CENTER RIGHT BOTTOM

3. React 小组件

对业务系统中常见的几种布局进行封装,提升编程效率,避免被 CSS 细节淹没。

3.1. 场景覆盖

场景1:

import React from "react" import {RowFlex, FlexItem, ColumnFlex} from "../components/flex" export default function Layout1(){ return ( FlexItem -> height="auto" -> 高度由内容决定 例如:这里放置网站标题栏 FlexItem -> 自适应区域 -> 自动填充剩余空间 FlexItem -> overflow:auto -> 当自适应区域内容要溢出自适应容器时,使用滚动条 这是内容区域 ); }

场景2:

import React from "react" import {RowFlex, FlexItem, ColumnFlex} from "../components/flex" export default function Layout2(){ return ( RowFlex 水平方向特性:在水平方向上,实现部分固定,部分自适应能力 水平方向支持百分比、支持固定宽度 竖直方向特性:高度由内容决定 -> 如果有滚动条 -> 出现在 RowFlex 的容器元素身上 基本上是,为使用布局,单独使用RowFlex,只是需要它的水平方向控制能力 左侧300 右侧900 ); }

场景3:

import React from "react" import {RowFlex, FlexItem, ColumnFlex} from "../components/flex" export default function Layout3(){ return ( RowFlex 水平方向特性:在水平方向上,实现部分固定,部分自适应能力 水平方向支持百分比、支持固定宽度 竖直方向特性:高度充满容器 -> 如果有滚动条 -> 各分区出现滚动条 基本上是,RowFlex 与 ColumnFlex 混合使用,例如,系统首页中的 Tree 与 Leaf 左侧300,这个区域没有滚动条 右侧900,这个区域有滚动条 ); }

3.2. 关键代码

index.less:

@flexPrefixCls: mousex-flex; /* flexbox */ .@{flexPrefixCls} { display: flex; &&-row { flex-direction: row; } &&-column { height: 100%; flex-direction: column; } & &-item { &-auto { flex: none; } &-fixed { flex: none; } &-fill { flex: 1; } // 分区滚动条处理 &-overflow-auto{ overflow: auto } &-overflow-hidden{ overflow: hidden } } }

RowFlex.less:

import React from 'react'; import classNames from 'classnames'; export interface RowFlexProps { prefixCls?: string, className?: string, style?: React.CSSProperties, height?: number | string, } export default class RowFlex extends React.Component { static defaultProps = { prefixCls: 'mousex-flex', }; render() { const { prefixCls, className, style, height, children, } = this.props; const wrapCls = classNames(prefixCls, className, { [`${prefixCls}-row`]: true }); let cssStyle = {}; if (height) { cssStyle = { ...cssStyle, height } } if (style) { cssStyle = { ...cssStyle, ...style } } return ( {children} ); } }

FlexItem.tsx:

import classNames from 'classnames'; import * as React from 'react'; export interface FlexItemProps { prefixCls?: string; className?: string; style?: React.CSSProperties; flexBasic?: number | string | "auto" | "fill"; overflow?: "auto" | "hidden" } const FlexItem: React.FunctionComponent = (props) => { const { children, className, prefixCls, style, flexBasic, overflow, ...restProps } = props; let cssStyle = { }; if (flexBasic !== "auto" && flexBasic !== "fill") { cssStyle = { ...cssStyle, flexBasis: flexBasic }; } if(style){ cssStyle = { ...cssStyle, ...style }; } const wrapCls = classNames(`${prefixCls}-item`, className, { [`${prefixCls}-item-auto`]: flexBasic === "auto", [`${prefixCls}-item-fill`]: flexBasic === "fill", [`${prefixCls}-item-fixed`]: flexBasic !== "auto" && flexBasic !== "fill", [`${prefixCls}-item-overflow-auto`]: overflow === "auto", [`${prefixCls}-item-overflow-hidden`]: overflow === "hidden" }); return ( {children} ); }; FlexItem.defaultProps = { prefixCls: 'mousex-flex', flexBasic: "fill", overflow: "auto", }; export default FlexItem;

参考:

can i use: https://www.caniuse.com/#feat=flexbox MDN: https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox CSS Flexible Box Layout Module Level 1: https://www.w3.org/TR/css-flexbox-1/



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3