首页 文章

在CSS Flexbox中,为什么没有“justify-items”和“justify-self”属性?

提问于
浏览
454

考虑flex容器的主轴和横轴:

资料来源:W3C

要沿主轴对齐flex项,有一个属性:

要沿横轴对齐弹性项,有三个属性:

在上图中,主轴是水平的,横轴是垂直的 . 这些是Flex容器的默认方向 .

但是,这些方向可以轻松地与flex-direction属性互换 .

/* main axis is horizontal, cross axis is vertical */
flex-direction: row;
flex-direction: row-reverse;

/* main axis is vertical, cross axis is horizontal */    
flex-direction: column;
flex-direction: column-reverse;

(横轴始终垂直于主轴 . )

我在描述轴' work is that there doesn' t似乎对任何一个方向都有什么特别之处 . 主轴,横轴,它们在重要性方面都是相同的,并且 flex-direction 可以很容易地来回切换 .

那么为什么横轴有两个额外的对齐属性?

为什么 align-contentalign-items 合并为主轴的一个属性?

为什么主轴没有得到 justify-self 属性?


这些属性有用的场景:

  • 将弹性项放置在弹性容器的角落中
    #box3 { align-self: flex-end; justify-self: flex-end; }

  • 使一组弹性项目对齐( justify-content: flex-end ),但第一个项目左对齐( justify-self: flex-start

考虑带有一组导航项和徽标的 Headers 部分 . 使用 justify-self 时,徽标可以左对齐,而导航项目保持最右边,整个内容可以平滑地调整("flexes")到不同的屏幕尺寸 .

  • 在一行三个弹性项目中,将中间项目粘贴到容器的中心( justify-content: center )并将相邻的项目对齐到容器边缘( justify-self: flex-startjustify-self: flex-end ) .

请注意,如果相邻项目具有不同的宽度,则 justify-content 属性上的值 space-aroundspace-between 将不会使中间项目相对于容器居中 .

#container {
  display: flex;
  justify-content: space-between;
  background-color: lightyellow;
}
.box {
  height: 50px;
  width: 75px;
  background-color: springgreen;
}
.box1 {
  width: 100px;
}
.box3 {
  width: 200px;
}
#center {
  text-align: center;
  margin-bottom: 5px;
}
#center > span {
  background-color: aqua;
  padding: 2px;
}
<div id="center">
  <span>TRUE CENTER</span>
</div>

<div id="container">
  <div class="box box1"></div>
  <div class="box box2"></div>
  <div class="box box3"></div>
</div>

<p>note that the middle box will only be truly centered if adjacent boxes are equal width</p>

jsFiddle version


在撰写本文时,flexbox spec中没有提及 justify-selfjustify-items .

然而,在CSS Box Alignment Module中,这是W3C未完成的建议,即 Build 一套通用的对齐属性以供所有盒子模型使用,有以下几点:

资料来源:W3C

您会注意到 justify-selfjustify-items 正在考虑中......但不适用于flexbox .


最后,我将重申主要问题:

为什么没有“辩护物品”和“自我辩护”属性?

5 回答

  • 15

    我知道这不是答案,但我值得 . 如果他们能够为flexbox发布 justify-self 以使其真正灵活,那将会很棒 .

    我认为,当轴上有多个项目时, justify-self 表现最合理的方式是将自身与最近的邻居(或边缘)对齐,如下所示 .

    我真的希望,W3C会注意到这一点,至少会考虑它 . =)

    这样,无论左右框的大小如何,您都可以拥有一个真正居中的项目 . 当其中一个盒子到达中心盒的位置时,它将简单地推动它直到没有更多的空间来分配 .

    制作精美布局的难易程度是无穷无尽的,看看这个“复杂”的例子 .

  • 1

    沿主轴对齐Flex项目的方法

    如问题中所述:

    要沿主轴对齐弹性项,有一个属性:justify-content要沿着交叉轴对齐弹性项,有三个属性:align-content,align-items和align-self .

    然后问题是:

    为什么没有正当理由和合理的自我属性?

    答案可能是:因为没有必要 .

    flexbox specification提供了两种沿主轴对齐flex项目的方法:


    对齐内容

    justify-content属性沿着flex容器的主轴对齐flex项 .

    它适用于Flex容器,但仅影响flex项目 .

    有五种对齐选项:

    • flex-start ~Flex项目在行的开头打包 .

    • flex-end ~Flex项目在行尾填充 .

    • center ~Flex项目朝向线条的中心打包 .

    • space-between ~Flex项目均匀分布,第一个项目与容器的一个边缘对齐,最后一个项目与相对边缘对齐 . 第一个和最后一个项目使用的边缘取决于flex-directionwriting modeltrrtl ) .

    • space-around ~与 space-between 相同,但两端都有半角空格 .


    自动边距

    使用auto margins,弹性项目可以居中,间隔或打包到子组中 .

    与应用于弹性容器的 justify-content 不同, auto 边距继续使用弹性项目 .

    它们通过消耗指定方向上的所有可用空间来工作 .


    将柔性项目组对齐到右侧,但是左侧的第一个项目

    问题的情景:

    使一组flex项目右对齐(justify-content:flex-end),但让第一个项目左对齐(justify-self:flex-start)考虑带有一组导航项和徽标的 Headers 部分 . 通过自我调整,徽标可以左对齐,而导航项目保持最右边,整个事物可以平滑地调整(“弯曲”)到不同的屏幕尺寸 .


    Other useful scenarios:


    将弯曲项目放在角落里

    问题的情景:

    将弹性项放置在角落.box {align-self:flex-end;自我辩护:flex-end; }


    垂直和水平居中放置弹性项目

    margin: autojustify-content: centeralign-items: center 的替代方案 .

    而不是Flex容器上的此代码:

    .container {
        justify-content: center;
        align-items: center;
    }
    

    您可以在flex项上使用它:

    .box56 {
        margin: auto;
    }
    

    centering a flex item that overflows the container这个替代方案很有用 .


    居中弹性项目,并在第一个和边缘之间居中第二个弹性项目

    Flex容器通过分配可用空间来对齐Flex项目 .

    因此,为了产生相等的 balancer ,使得中间物品可以在容器中居中并且单个物品旁边,必须引入 balancer .

    在下面的示例中,引入不可见的第三弹性项目(框61和68)以 balancer “真实”项目(框63和66) .

    当然,这种方法在语义方面并不是很好 .

    或者,您可以使用伪元素而不是实际的DOM元素 . 或者你可以使用绝对定位 . 这里介绍了所有三种方法: Center and bottom-align flex items

    注意:上面的示例仅适用于 - 在真正居中方面 - 当最外面的项目的高度/宽度相等时 . 当flex项目的长度不同时,请参阅下一个示例 .


    当相邻项目的大小不同时,将Flex项目居中

    问题的情景:

    在一行三个弹性项目中,将中间项目粘贴到容器的中心(对齐内容:中心)并将相邻的项目对齐到容器边缘(自我调整:flex-start和justify-self:flex-结束) . 请注意,如果相邻项具有不同的宽度,则在justify-content属性上的值space-around和space-between将不会使中间项相对于容器居中(请参阅演示) .

    如上所述,除非所有弹性项目的宽度或高度相等(取决于 flex-direction ),否则中间项目不能真正居中 . 这个问题为 justify-self 属性(当然是为处理任务而设计)提供了强有力的理由 .

    #container {
      display: flex;
      justify-content: space-between;
      background-color: lightyellow;
    }
    .box {
      height: 50px;
      width: 75px;
      background-color: springgreen;
    }
    .box1 {
      width: 100px;
    }
    .box3 {
      width: 200px;
    }
    #center {
      text-align: center;
      margin-bottom: 5px;
    }
    #center > span {
      background-color: aqua;
      padding: 2px;
    }
    
    <div id="center">
      <span>TRUE CENTER</span>
    </div>
    
    <div id="container">
      <div class="box box1"></div>
      <div class="box box2"></div>
      <div class="box box3"></div>
    </div>
    
    <p>The middle box will be truly centered only if adjacent boxes are equal width.</p>
    

    以下是解决此问题的两种方法:

    Solution #1: Absolute Positioning

    flexbox规范允许absolute positioning of flex items . 这允许中间项目完全居中,而不管其兄弟姐妹的大小 .

    请记住,与所有绝对定位的元素一样,这些项目将从document flow中删除 . 这意味着它们不占用容器中的空间并且可以与它们的兄弟姐妹重叠 .

    在下面的示例中,中间项目以绝对定位为中心,外部项目保持在流动中 . 但是可以以相反的方式实现相同的布局:使用 justify-content: center 居中中间项目并绝对定位外部项目 .

    Solution #2: Nested Flex Containers (no absolute positioning)

    .container {
      display: flex;
    }
    .box {
      flex: 1;
      display: flex;
      justify-content: center;
    }
    .box71 > span { margin-right: auto; }
    .box73 > span { margin-left: auto;  }
    
    /* non-essential */
    .box {
      align-items: center;
      border: 1px solid #ccc;
      background-color: lightgreen;
      height: 40px;
    }
    
    <div class="container">
      <div class="box box71"><span>71 short</span></div>
      <div class="box box72"><span>72 centered</span></div>
      <div class="box box73"><span>73 loooooooooooooooong</span></div>
    </div>
    

    以下是它的工作原理:

    • 顶级div( .container )是一个弹性容器 .

    • 每个子div( .box )现在是一个弹性项目 .

    • 每个 .box 项目都是 flex: 1 ,以便平均分配容器空间 .

    • 现在这些项目消耗了行中的所有空间并且宽度相等 .

    • 使每个项目成为(嵌套的)Flex容器并添加 justify-content: center .

    • 现在每个 span 元素都是一个居中的弹性项目 .

    • 使用flex auto margin来向左和向右移动外部 span .

    您也可以放弃 justify-content 并仅使用 auto 边距 .

    justify-content 可以在这里工作,因为 auto 边距始终具有优先权 . 从规格:

    8.1 . 与自动边距对齐在通过justify-content和align-self进行对齐之前,任何正空闲空间都会分配到该维度中的自动边距 .


    justify-content:space-same(concept)

    回到justify-content一分钟,这是另一个选择的想法 .

    • space-same ~ space-betweenspace-around 的混合体 . Flex项目间隔均匀(如 space-between ),除了两端的半角空格(如 space-around ),两端都有全尺寸空格 .

    可以使用Flex容器上的::before::after伪元素来实现此布局 .

    (信用:代码为@oriol,标签为@crl)

    UPDATE: 浏览器已经开始实现 space-evenly ,它完成了上述工作 . 有关详细信息,请参阅此帖:Equal space between flex items


    PLAYGROUND(包括上述所有示例的代码)

  • 91

    这是在www样式列表和Tab Atkins(规范编辑器)provided an answer explaining why上询问的 . 我在这里详细说明一下 .

    首先,让我们假设我们的flex容器是单行的( flex-wrap: nowrap ) . 在这种情况下,在主轴上有意义(因为那里,项目是统一对齐的) .

    对于多线flexbox,相同的逻辑适用于每个“柔性线” . 在给定的行中,项目是在横轴上单独对齐(因为在每个线上只有一个项目,在横轴上),而在主轴上是统一的 .


    这是另一种表达方式:所以 *-self*-content 属性都是关于如何在事物周围分配额外空间 . 但关键的区别在于 *-self 版本适用于该轴中只有一个东西的情况, *-content 版本适用于该轴中可能有许多东西的情况 . 单项与多项情景是不同类型的问题,因此它们具有不同类型的可用选项 - 例如, space-around / space-between 值对 *-content 有意义,但不适用于 *-self .

    SO:在flexbox的主轴上,有许多东西可以分配空间 . 所以 *-content 属性在那里是有意义的,但不是 *-self 属性 .

    相反,在横轴中,我们同时具有 *-self*-content 属性 . 一个确定我们如何在许多柔性线周围分布空间( align-content ),而另一个( align-self )确定如何在给定柔性线内的横轴上的各个柔性项周围分布空间 .

    (我在这里忽略了 *-items 属性,因为它们只是为 *-self Build 了默认值 . )

  • 867

    justify-self ,但在Chrome Canary中,不是Chrome稳定版 . 甚至有 justify-items

    但据我所知,这些属性也不起作用 . 因此,谷歌可能会事先为未来的CSS版本保存它 . 只能希望他们能尽快添加这些属性 .

  • -3

    justify-items .

    我认为这是一个新功能 . 浏览器兼容性有点缺乏 .

相关问题