Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
412 views
in Technique[技术] by (71.8m points)

html - Understanding the flex property

Why, in this example, is the .main element (blue) dividing space only with .aside-1 (yellow) and .aside-2 (pink), and not with all elements?

enter image description here

We have a wrapper that is putting all elements occupying one line.

In .main we say flex: 3 0px, which I think says, this element will be 3x bigger than the other four elements and will occupy 3/(3+1+1+1+1).

However, I've noticed that with a nowrap wrapper the smallest item is .main.

And with wrap, it divides with the two closest elements.

Can't understand this.

.wrapper {
  display: flex;
  flex-flow: row wrap;
  font-weight: bold;
  text-align: center;
}

.wrapper>* {
  padding: 10px;
  flex: 1 100%;
}

.header {
  background: tomato;
}

.footer {
  background: lightgreen;
}

.main {
  text-align: left;
  background: deepskyblue;
  height: 50vh;
  flex: 3 0px;
}

.aside-1 {
  background: gold;
}

.aside-2 {
  background: hotpink;
}

.aside {
  flex: 1 auto;
}

.aside-1 {
  order: 1;
}

.main {
  order: 2;
}

.aside-2 {
  order: 3;
}

.footer {
  order: 4;
}
<div class="wrapper">
  <header class="header">Header</header>
  <article class="main">
    <p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est.
      Mauris placerat eleifend leo.</p>
  </article>
  <aside class="aside aside-1">Aside 1</aside>
  <aside class="aside aside-2">Aside 2</aside>
  <footer class="footer">Footer</footer>
</div>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

First take a look at this rule in your code:

.wrapper > * {
  padding: 10px;
  flex: 1 100%;
}

The selector above is targeting all five flex items:

  • header
  • article
  • aside
  • aside
  • footer

The flex component breaks down to this:

  • flex-grow: 1
  • flex-shrink: 1 (by default)
  • flex-basis: 100%

You wrote:

Why, in this example, is the .main element (blue) dividing space only with .aside-1 (yellow) and .aside-2 (pink), and not with all elements?

This is why:

  1. The container is set to flex-flow: row wrap, meaning flex items are allowed to wrap.
  2. As noted above, all flex items are set to flex-basis: 100% (i.e. width: 100%), meaning there can only be one flex item per row, except...
  3. flex-basis: 100% only gets applied to the header and footer because...
  4. it is being overridden by other rules later in the cascade sequence1:

    .main { flex: 3 0px; }
    
    .aside { flex: 1 auto; }
    

However, I've noticed that with a nowrap wrapper the smallest item is .main.

Yes, because, as mentioned above, it has flex-basis: 0 and flex-shrink: 1.

In .main we say flex: 3 0px, which I think says, this element will be 3x bigger than the other four elements and will occupy 3/(3+1+1+1+1).

Not quite. flex-grow: 3 means that the element will consume 3x the amount of free space than other flex items with flex-grow: 1. It doesn't necessarily mean it will be 3x the size. More details here: flex-grow not sizing flex items as expected


1 It may appear that specificity should win over the cascade, and all items should get flex-basis: 100%:

  • .wrap > * { flex-basis: 100%; } vs .main { flex: 3 0px; }
  • .wrap > * { flex-basis: 100%; } vs aside { flex: 1 auto; }

Except that the universal selector (*) has zero specificity. So in this case, all selectors have equal specificity and source order matters.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...