盒子模型的弹性盒

CSS3 弹性盒( Flexible Box 或 flexbox),是一种当页面需要适应不同的屏幕大小以及设备类型时确保元素拥有恰当的行为的布局方式。对于很多应用来讲,弹性盒改进了盒模型,既不使用浮动,也不会在弹性盒容器与其内容之间合并外边距。

许多设计师会发现弹性盒容易上手。弹性盒中的子元素通过在各个方向放置就可以以弹性的尺寸适应父元素的显示区域。由于子元素的显示顺序和它们在代码中 的顺序是独立的,通过使用弹性盒,定位子元素变得更加简单,复杂的布局也能够使用更清晰的代码更简单的实现。独立显示被设定成只针对可见元素,而不是基于代码的声明和导航顺序。

弹性盒概念

弹性盒布局的定义中,它可以自动调整子元素的高和宽,来很好的填充任何显示设备中的可用显示空间,收缩内容防止内容溢出。

不同于盒布局的基于垂直方向以及行内布局的基于水平方向,弹性盒布局的算法是方向无关的。 虽然盒布局在页面中工作良好,但是其定义不足以支持那种需要根据用户代理从竖直切换成水平等变化而进行方向切换、大小调整、拉伸、收缩的引用组件。不同于将要出现的网格布局针对目标为大比例布局,弹性盒布局更适用于应用组件和小比例布局。这两种都是CSS工作组为了能与不同用户代理、不同书写模式和其他弹性需要进行协作而做出的努力。

弹性盒布局名词

虽然弹性盒布局的讨论中自由地使用了如水平轴、内联轴和垂直轴、块级轴的词汇,仍然需要一个新的词汇表来描述这种模型。参考下面的图形来学习后面的词汇。图形显示了弹性容器有一个值为row的属性flex-direction,其意义在于包含的子元素相互之间会根据书写模式和文本流方向在主轴上水平排列,即从左到右。

flex_terms.png

弹性容器
弹性子元素的父元素。 通过设置display 属性的值为flex 或 inline-flex将其定义为弹性容器。
弹性子元素

弹性容器的每一个子元素变为一个弹性子元素。弹性容器直接包含的文本变为匿名的弹性子元素。

每个弹性盒布局以两个轴来排列。弹性子元素沿着主轴依次相互排列。侧轴垂直于主轴

  • 属性 flex-direction 定义主轴方向。
  • 属性 justify-content 定义了弹性子元素如何在当前线上沿着主轴排列。
  • 属性 align-items 定义了弹性子元素如何在当前线上沿着侧轴排列。
  • 属性 align-self 覆盖父元素的align-items属性,定义了单独的弹性子元素如何沿着侧轴排列。
方向

弹性容器的主轴开始主轴结束侧轴开始侧轴结束边缘代表了弹性子元素排列的起始和结束位置。它们具体取决于由writing-mode(从左到右、从右到左等等)属性建立的向量中的主轴和侧轴位置。

弹性子元素根据 flex-wrap 属性控制的侧轴方向(在这个方向上可以建立垂直的新线),既可以是一行也可以是多行排列。

尺寸

弹性子元素宽高可相应地等价于主尺寸侧尺寸,它们都分别取决于弹性容器的主轴和侧轴。

建立弹性盒子

使用CSS建立弹性盒子样式,为 display 指定下面的值:

display : flex
 

或者

display : inline-flex
 

这样做将元素定义为弹性容器,其子元素即弹性子元素。 flex 值表示弹性容器为块级。inline-flex 值表示弹性容器为原子行级元素 。

注意:浏览器厂商的前缀标记,是加在属性值而不是向属性名前面。如:display:-webkit-flex

弹性子元素的注意事项

包含在弹性容器内的文本自动成为匿名的弹性子元素。然而,只包含空白的弹性子元素不会被渲染,就好像它被设定为 display:none 一样。

弹性容器的绝对定位的子元素会被定位,因此其静态位置会根据它们的弹性容器的主起始内容盒的角落上开始。

目前由于一个已知的问题,在弹性子元素上指定 visibility:collapse
会导致其好像被指定了 display:none 一样,但该操作的初衷是使元素具有好像被指定了 visibility:hidden 一样的效果。在该问题被解决之前建议使用visibility:hidden ,其效果在弹性子元素上等同于 visibility:collapse 。

相邻的弹性子元素不会发生外边距合并。使用 auto 的外边距会在垂直和水平方向上带来额外的空间,这种性质可用于对齐或分隔临近的弹性子元素。W3C弹性盒子布局模型的 使用'auto'的外边距进行对齐 部分有更多信息。

为了保证弹性子元素有一个合理的默认最小尺寸,使用 min-auto 与 min-height:auto。对于弹性子元素, auto 属性计算其最小的宽高不小于其内容的尺寸,保证在渲染时其大小足够容纳内容。 min-width 和 min-height 部分有更多信息

弹 性盒子的对齐会进行真正的居中,不像CSS的其他居中方法。这意味着即使弹性容器溢出,子元素仍然保持居中。有些时候这可能有问题,然而即使溢出了页面的 上沿,或左边沿(在从左到右的语言如英语;这个问题在从右到左的语言中发生在右边沿,如阿拉伯文),因为你不能滚动到那里,即使那里有内容!在将来的版本 中,对齐属性会被扩展为有一个“安全”选项。目前,如果关心这个问题,你可以使用外边距来达到居中的目的,这种方式比较“安全”,在溢出的情况下会停止居 中。在你想要居中的弹性子元素上应用自动外边距代替align-属性。在弹性容器的第一个和最后一个子元素的外侧应用自动外边距来代替justify-属性。自动外边距会伸缩并假定剩余空间,当有剩余空间时居中弹性子元素,没有剩余空间时切换会正常对齐模式。然而,如果你想要在多线弹性盒子中用基于外边距的居中替换justify-content属性,你可能就没那么幸运了,因为你需要在每一线的第一个和最后一个元素上应用外边距。除非你能提前预测哪个元素是哪一线上的最后一个元素,否则你没法稳定地在主轴上用基于外边距的居中代替 justify-content 属性

说起虽然元素的显示顺序与源代码中的顺序无关,这种无关仅对显示效果有效,不包括语音顺序和基于源代码的导航。即使是 order 也不影响语言和导航序列。因此开发者必须小心排列源代码中的元素以免破坏文档的可访问性。

弹性盒子的属性

Flexible-boxes-related properties: marginalign-contentalign-itemsalign-selfdisplayflexflex-basisflex-directionflex-flowflex-grow,flex-shrinkflex-wrapjustify-contentmin-heightmin-widthorder

不影响弹性盒子的属性

因为弹性盒子使用一种不同的布局逻辑,一些属性会在弹性容器上无效。

  • 多列模块 中的column-*属性对弹性子元素无效。
  • float 和 clear 对弹性子元素无效。使用 float 会导致 display 属性计算为 block.
  • vertical-align 对弹性子元素的对齐无效。

例子

基于弹性布局的例子

这个基本的例子展示了如何对元素应用弹性布局以及在弹性布局中子元素的行为。

<!DOCTYPE html>
<html lang="en">
  <head>
    <style>

   .flex
   {
      /* basic styling */
      width: 350px;
      height: 200px;
      border: 1px solid #555;
      font: 14px Arial;

      /* flexbox setup */
      display: -webkit-flex;
      -webkit-flex-direction: row;

      display: flex;
      flex-direction: row;
   }

   .flex > div
   {
      -webkit-flex: 1 1 auto;
      flex: 1 1 auto;

      width: 30px; /* To make the transition work nicely.  (Transitions to/from
                      "auto" are buggy in Gecko and Webkit, at least.
                      See http://bugzil.la/731886 for more info.) */

      -webkit-transition: width 0.7s ease-out;
      transition: width 0.7s ease-out;
   }

   /* colors */
   .flex > div:nth-child(1){ background : #009246; }
   .flex > div:nth-child(2){ background : #F1F2F1; }
   .flex > div:nth-child(3){ background : #CE2B37; }

   .flex > div:hover
   {
        width: 200px;
   }
   
   </style>
    
 </head>
 <body>
  <p>Flexbox nuovo</p>
  <div class="flex">
    <div>uno</div>
    <div>due</div>
    <div>tre</div>
  </div>
 </body>
</html>
 

绝妙的弹性布局例子

这个例子说明了弹性布局如何根据不同的屏幕分辨率提供动态改变布局的能力。下图展示了这种转换。

HolyGrailLayout.png

这个例子正适用于桌面浏览器网页必须优化以适应于智能手机屏幕的场景。不仅仅需要元素减小尺寸,它们排列的顺序方式也必须改变。弹性布局很容易实现这种需求。

<!DOCTYPE html>
<html lang="en">
  <head>
    <style>

  body {
   font: 24px Helvetica;
   background: #999999;
  }

  #main {
   min-height: 800px;
   margin: 0px;
   padding: 0px;
   display: -webkit-flex;
   display:         flex;
   -webkit-flex-flow: row;
           flex-flow: row;
   }
 
  #main > article {
   margin: 4px;
   padding: 5px;
   border: 1px solid #cccc33;
   border-radius: 7pt;
   background: #dddd88;
   -webkit-flex: 3 1 60%;
           flex: 3 1 60%;
   -webkit-order: 2;
           order: 2;
   }
  
  #main > nav {
   margin: 4px;
   padding: 5px;
   border: 1px solid #8888bb;
   border-radius: 7pt;
   background: #ccccff;
   -webkit-flex: 1 6 20%;
           flex: 1 6 20%;
   -webkit-order: 1;
           order: 1;
   }
  
  #main > aside {
   margin: 4px;
   padding: 5px;
   border: 1px solid #8888bb;
   border-radius: 7pt;
   background: #ccccff;
   -webkit-flex: 1 6 20%;
           flex: 1 6 20%;
   -webkit-order: 3;
           order: 3;
   }
 
  header, footer {
   display: block;
   margin: 4px;
   padding: 5px;
   min-height: 100px;
   border: 1px solid #eebb55;
   border-radius: 7pt;
   background: #ffeebb;
   }
 
  /* Too narrow to support three columns */
  @media all and (max- 640px) {
  
   #main, #page {
    -webkit-flex-flow: column;
            flex-flow: column;
   }

   #main > article, #main > nav, #main > aside {
    /* Return them to document order */
    -webkit-order: 0;
            order: 0;
   }
  
   #main > nav, #main > aside, header, footer {
    min-height: 50px;
    max-height: 50px;
   }
  }

 </style>
  </head>
  <body>
 <header>header</header>
 <div id='main'>
    <article>article</article>
    <nav>nav</nav>
    <aside>aside</aside>
 </div>
 <footer>footer</footer>
  </body>
</html>

操作

有几个在线的弹性盒子操作站点可用于实验:

始终要记得的一些事

描述弹性子元素如何排列的逻辑有时候非常隐晦。这是一些在计划使用弹性盒子时应避免的一些事。

弹性盒子会根据书写模式的需要进行排列。这意味着主起始点主结束点需要根据开始结束点布局。

侧起始点侧结束点取决于依赖 direction 属性值的开始结束点的定义

只要 break- 属性允许,断页可能出现在弹性盒子布局中。CSS3的 break-after, break-before 和 break-inside a以及CSS2.1的 page-break-beforepage-break-after 和 page-break-inside 属性可能出现在弹性容器,弹性子元素以及弹性子元素的内部元素上出现。

浏览器兼容性

 

FeatureFirefox (Gecko)ChromeInternet ExplorerOperaSafari
Basic support (single-line flexbox) 18.0 (18.0)-moz(Behind a pref) [2]
22.0 (22.0) [2]
21.0-webkit
29.0
11 [3] 12.10
15-19 -webkit
6.1-webkit [1]
Multi-line flexbox 28.0 (28.0) 21.0-webkit
29.0
11 [3] 12.10
15-19 -webkit
6.1-webkit [1]

 

注释

[1]  Safari <= 6.0 ( 6.1 for iOS )  支持旧草案标准。 Safari 6.1( 7 for iOS ) 支持新标准。

[2]  Firefox 22 之前若想支持 flexbox,需要在配置( about:config ) 里将 "layout.css.flexbox.enabled" 设为 true 。 Firefox 22 至 Firefox 27 默认为 true 。 Firefox 28 删除了这个配置项。

[3] Internet Explorer 10 支持旧草案标准,并且需要前缀 -ms,参见 这里 ;Internet Explorer 11 支持新的标准,不需要前缀,参见 这里

[4] Android browser <= 4.3 支持旧草案标准;Android 4.4 支持新标准。

注: 上面提到支持旧草案标准, 实际上不同浏览器之间语法不一样,并且都不是完全实现。

原文地址:https://www.cnblogs.com/hbyzs/p/4459321.html