为什么设置flex:1之后,再设width不生效?

787 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第2天,点击查看活动详情

前些天,接了私活在干,项目类型是大屏可视化,主要的工作内容分为两部分,修改已完成页面和新增页面。 在修改页面过程中,发现不少地方都用到flex:1,最开始的时候,主要做内容的修改,不涉及布局,没有太在意,后来需求改变,页面基本推倒重来,就牵扯到了重新布局,在修改代码的过程中,flex:1带来了不少麻烦。

flex:1包含了三个属性,分别是:flex-grow、flex-shrink、flex-basis。

flex-grow: 1;
flex-shrink: 1;
flex-basis: 0%;

flex-grow 拉伸因子,默认值为0,表示如果存在剩余空间,也不放大,flex-grow的值为整数。 当flex-grow:1时,flex项目会平均剩余可用的空间。一定要注意的是,等分剩余宽度,而剩余宽度是总宽度减去内容宽度,再进行等分。而且这个等分甚至还是根据内容多少来等分,有的内容多,他等分还多一些。可以通过如下的公式计算flex项目的宽度

项目宽度 = (( flex-grow / flex-grow 总个数) * 可用空间)+ 初始项目宽度

也可以这样理解,所有项目的flex-grow为1:等分剩余空间(自动放大占位); flex-grow为n的项目,占据的空间(放大的比例)是flex-grow为1的n倍;flex-grow:0时,保持其初始宽度。

flex-shrink收缩规则,默认值为1,表示如果空间不足,该项目将缩小。当子容器的宽度相加大于父容器时,这时会产生一个缺少的空间,(子元素默认超出父容器是不会换行的,因为flex-wrap默认值为auto),因此按照flex-shrink的值,子容器会等比进行收缩。

flex-basis伸缩基数,默认值为auto,可以近似当作子容器的宽度width,只不过flex-basis的优先级会高于width(注意:这两个中有一个是auto,另一个非auto的优先级会更高),flex-basis可以设为跟width或height属性一样的值(比如350px,默认值为 auto),则项目将占据固定空间。如果将 flex-basis 设置为 100%,该项目单独占一行,其他项目将换行。

情况①:flex 项目的大小取决于内容。因此,内容越多的flex项目就会越大。

.item { 
    /* 默认值,相当于 flex:1 1 auto */ 
    flex: auto; 
} 

情况②:flex项目大小会保持一致。

.item { 
    /* 相当于  flex: 1 1 0% */ 
    flex1; 
} 

对于flex属性:

  1. flex-grow: 1,flex-shrink:1, flex-basic: 0。
.item { 
    flex1; 
} 
  1. flex-grow: 2,flex-shrink:1, flex-basic: 0。
.item { 
    flex2; 
} 
  1. flex-grow: 1,flex-shrink:1, flex-basic: 0。
.item { 
    flex1 1; 
} 
  1. flex-grow: 1,flex-shrink:1, flex-basic: 100px。
.item { 
    flex100px; 
    /* flex: 1 1 100px */ 
} 
  1. flex-grow: 0,flex-shrink:1, flex-basic: 0。
.item { 
    flex0; 
} 
  1. flex-grow: 1,flex-shrink:1, flex-basic: 0。
.item { 
    flex0%; 
    /* flex: 1 1 0% */ 
} 

注意: flex: 0,是将flex-grow置为0,但flex: 0%或者flex: 0px,是将flex-basis置为0

当你需要设置grow、shrink和basis时,最好使用flex属性来实现这个目的。

根据 CSS 规范:

  • 建议开发者使用 flex 简写来控制灵活性,而不是直接使用它的普通属性,因为简写的可以正确地重置任何未指定的组件以适应常见情景。