Home > Software engineering >  Why don't flex children share equal widths with text content when flex grow is 1
Why don't flex children share equal widths with text content when flex grow is 1

Time:06-06

Why does one two not take up take space, all have flex: 1, so I want all to have equal widths, sharing the width of the parent.

How do I tweak it so damn takes less space than other two.

.wrap {
  display: flex;

  background: #ccc;
}

.one {
flex: 1;
  background: red;
}

.two {
flex: 1;
  background: yellow;
}

.damn {
flex: 1;
  background: blue;
}
<div class='wrap'>
  <div class='one'>Hello</div>
  <div class='two'>World</div>
  <div class='damn'>
<vchessreplay><moves><move ><index>1.</index>d4</move><comment></comment><move >d5</move><comment></comment><move ><index>2.</index>Bf4</move><comment></comment><move >c5</move><comment></comment><move ><index>3.</index>e3</move><comment></comment><lines><line-><move ><index>3...</index>cxd4</move><comment></comment><move ><index>4.</index>exd4</move><comment></comment></line-><line-><move ><index>3...</index>Qb6</move><comment></comment><move ><index>4.</index>Nc3</move><comment></comment><move >e6</move><comment></comment><move ><index>5.</index>Nf3</move><comment></comment><lines><line-><move ><index>5...</index>Be7</move><comment> Hello world </comment><move ><index>6.</index>a5</move><comment> What s up ok ok ok ook </comment><move >Qd8</move><comment></comment></line-><line-><move ><index>5...</index>c4</move><comment></comment><move ><index>6.</index>b3</move><comment></comment><move >b5</move><comment></comment><move ><index>7.</index>Rb1</move><comment></comment><lines><line-><move ><index>7...</index>Qa5</move><comment></comment><lines><line-><move ><index>8.</index>Rxb7</move><comment></comment><move >Qxc3</move><comment></comment></line-><line-><move ><index>8.</index>Bxc4</move><comment></comment><move >Qxc7</move><comment></comment></line-></lines></line-><line-><move ><index>7...</index>Qd7</move><comment></comment><move ><index>8.</index>Ne5</move><comment></comment></line-></lines></line-></lines></line-></lines></moves></vchessreplay>
  </div>
</div>

CodePudding user response:

My reading of the question is that you wish to understand:

Why [do] one [and] two not take up an equal amount of space as .damn?

Assuming I'm correct in that interpretation, then take a look at the following demo:

// defining a named function using Arrow syntax, that
// takes one argument:
const report = (node) => {
    // declaring variables, using a destructuring
    // assignment here we retrieve the named-variables
    // from the Object returned by window.getComputedStyle
    // which creates the variable 'width' (and so on) by
    // retrieving the window.getComputedStyle(...).width
    // property-value:
    let {
      width,
      height,
      flexGrow,
      flexShrink,
      flexBasis
    } = window.getComputedStyle(node, null),
      // creating a <div> element:
      temp = document.createElement('div');
    // assigning the results of the function template()
    // to be the inner-HTML of the created <div>:
    temp.innerHTML = template({
      width,
      height,
      flexGrow,
      flexShrink,
      flexBasis
    });
    // prepending the <ol> from within the <div> to the node:
    node.prepend(temp.querySelector('ol'));
  },
  // another named function, using Arrow syntax:
  template = (v = {}) => {
    // returning a template literal string with the
    // various JavaScript variables interpolated:
    return `
<ol  style="--verticalOffset: ${v.height}">
  <li >height: <var>${v.height}</var></li>
  <li >width: <var>${v.width}</var></li>
  <li >flex-grow: <var>${v.flexGrow}</var></li>
  <li >flex-shrink: <var>${v.flexShrink}</var></li>
  <li >flex-basis: <var>${v.flexBasis}</var></li>
</ol>`
  }

// selecting all <div> elements within the .wrap element,
// iterating over that NodeList using
// NodeList.prototype.forEach(), and calling the report()
// function on each Node of the NodeList:
document.querySelectorAll('.wrap > div').forEach(report);
*,
::before,
::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.wrap {
  display: flex;
  background: #ccc;
}

.wrap>div {
  position: relative;
}

.one {
  flex: 1;
  background: red;
}

.two {
  flex: 1;
  background: yellow;
}

.damn {
  flex: 1;
  background: blue;
}

.report {
  display: grid;
  gap: 0.25em;
  background-color: #fff;
  border: 1px solid #393;
  position: absolute;
  inset: auto 10%;
  list-style-type: none;
  translate: 0 calc(var(--verticalOffset) - 2vmin);
}

.report::before {
  content: "Computed CSS property-values:";
}

.report li {
  background-color: #eee;
  display: flex;
  justify-content: space-between;
  padding: 0.2em;
}

.report li:nth-child(even) {
  background-color: #fff;
}

var {
  color: #393;
  font-weight: 400;
}
<div class='wrap'>
  <div class='one'></div>
  <div class='two'></div>
  <div class='damn'>
<vchessreplay><moves><move ><index>1.</index>d4</move><comment></comment><move >d5</move><comment></comment><move ><index>2.</index>Bf4</move><comment></comment><move >c5</move><comment></comment><move ><index>3.</index>e3</move><comment></comment><lines><line-><move ><index>3...</index>cxd4</move><comment></comment><move ><index>4.</index>exd4</move><comment></comment></line-><line-><move ><index>3...</index>Qb6</move><comment></comment><move ><index>4.</index>Nc3</move><comment></comment><move >e6</move><comment></comment><move ><index>5.</index>Nf3</move><comment></comment><lines><line-><move ><index>5...</index>Be7</move><comment> Hello world </comment><move ><index>6.</index>a5</move><comment> What s up ok ok ok ook </comment><move >Qd8</move><comment></comment></line-><line-><move ><index>5...</index>c4</move><comment></comment><move ><index>6.</index>b3</move><comment></comment><move >b5</move><comment></comment><move ><index>7.</index>Rb1</move><comment></comment><lines><line-><move ><index>7...</index>Qa5</move><comment></comment><lines><line-><move ><index>8.</index>Rxb7</move><comment></comment><move >Qxc3</move><comment></comment></line-><line-><move ><index>8.</index>Bxc4</move><comment></comment><move >Qxc7</move><comment></comment></line-></lines></line-><line-><move ><index>7...</index>Qd7</move><comment></comment><move ><index>8.</index>Ne5</move><comment></comment></line-></lines></line-></lines></line-></lines></moves></vchessreplay>
  </div>
</div>

JS Fiddle demo.

This demo – as it positions the .report elements using position: absolute – doesn't affect the sizing of the elements to which they're appended, but shows the resulting property-values.

As you can see, they all have the same results for flex-grow, flex-shrink and flex-basis; so why don't they have the same results? The answer lies in the calculations performed by the browser to fit the content to the desired layout; as you have an untidied mess of HTML nested within that .damn element the opportunities at which the browser can start a new line are minimised, so the longest unbreakable line sets the overall width of the .damn element.

If, however we tidy up the HTML to allow new-lines and readability of the HTML within the .damn element, we get this:

const report = (node) => {
    let {
      width,
      height,
      flexGrow,
      flexShrink,
      flexBasis
    } = window.getComputedStyle(node, null),
      temp = document.createElement('div');
    temp.innerHTML = template({
      width,
      height,
      flexGrow,
      flexShrink,
      flexBasis
    });
    node.prepend(temp);
    return temp;
  },
  template = (v) => {
    return `
<ol  style="--verticalOffset: ${v.height}">
  <li >height: <var>${v.height}</var></li>
  <li >width: <var>${v.width}</var></li>
  <li >flex-grow: <var>${v.flexGrow}</var></li>
  <li >flex-shrink: <var>${v.flexShrink}</var></li>
  <li >flex-basis: <var>${v.flexBasis}</var></li>
</ol>`
  }

document.querySelectorAll('.wrap > div').forEach(report);
*,
::before,
::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.wrap {
  display: flex;
  background: #ccc;
}

.wrap>div {
  position: relative;
}

.one {
  flex: 1;
  background: red;
}

.two {
  flex: 1;
  background: yellow;
}

.damn {
  flex: 1;
  background: blue;
}

.report {
  display: grid;
  gap: 0.25em;
  background-color: #fff;
  border: 1px solid #393;
  position: absolute;
  inset: auto 10%;
  list-style-type: none;
  translate: 0 calc(var(--verticalOffset) - 2vmin);
}

.report::before {
  content: "Computed CSS property-values:";
}

.report li {
  background-color: #eee;
  display: flex;
  justify-content: space-between;
  padding: 0.2em;
}

.report li:nth-child(even) {
  background-color: #fff;
}

var {
  color: #393;
  font-weight: 400;
}
<div class='wrap'>
  <div class='one'></div>
  <div class='two'></div>
  <div class='damn'>
    <vchessreplay>
      <moves>
        <move >
          <index>1.</index>d4
        </move>
        <comment></comment>
        <move >d5</move>
        <comment></comment>
        <move >
          <index>2.</index>Bf4
        </move>
        <comment></comment>
        <move >c5</move>
        <comment></comment>
        <move >
          <index>3.</index>e3
        </move>
        <comment></comment>
        <lines>
          <line->
            <move >
              <index>3...</index>cxd4
            </move>
            <comment></comment>
            <move >
              <index>4.</index>exd4
            </move>
            <comment></comment>
          </line->
          <line->
            <move >
              <index>3...</index>Qb6
            </move>
            <comment></comment>
            <move >
              <index>4.</index>Nc3
            </move>
            <comment></comment>
            <move >e6</move>
            <comment></comment>
            <move >
              <index>5.</index>Nf3
            </move>
            <comment></comment>
            <lines>
              <line->
                <move >
                  <index>5...</index>Be7
                </move>
                <comment> Hello world </comment>
                <move >
                  <index>6.</index>a5
                </move>
                <comment> What s up ok ok ok ook </comment>
                <move >Qd8</move>
                <comment></comment>
              </line->
              <line->
                <move >
                  <index>5...</index>c4
                </move>
                <comment></comment>
                <move >
                  <index>6.</index>b3
                </move>
                <comment></comment>
                <move >b5</move>
                <comment></comment>
                <move >
                  <index>7.</index>Rb1
                </move>
                <comment></comment>
                <lines>
                  <line->
                    <move >
                      <index>7...</index>Qa5
                    </move>
                    <comment></comment>
                    <lines>
                      <line->
                        <move >
                          <index>8.</index>Rxb7
                        </move>
                        <comment></comment>
                        <move >Qxc3</move>
                        <comment></comment>
                      </line->
                      <line->
                        <move >
                          <index>8.</index>Bxc4
                        </move>
                        <comment></comment>
                        <move >Qxc7</move>
                        <comment></comment>
                      </line->
                    </lines>
                  </line->
                  <line->
                    <move >
                      <index>7...</index>Qd7
                    </move>
                    <comment></comment>
                    <move >
                      <index>8.</index>Ne5
                    </move>
                    <comment></comment>
                  </line->
                </lines>
              </line->
            </lines>
          </line->
        </lines>
      </moves>
    </vchessreplay>
  </div>
</div>

JS Fiddle demo.

Which you'll note is a lot closer to your expected result; this is because there are more opportunities for the content of .damn to reflow to new lines in order to allow for shorter lines of text within.

To have the .damn element be smaller, simply adjust your flex properties, so that it's a lower-value on the .damn element compared to the other two; for example .damn { flex: 1; } and .one, .two { flex: 2; }:

const report = (node) => {
    let {
      width,
      height,
      flexGrow,
      flexShrink,
      flexBasis
    } = window.getComputedStyle(node, null),
      temp = document.createElement('div');
    temp.innerHTML = template({
      width,
      height,
      flexGrow,
      flexShrink,
      flexBasis
    });
    node.prepend(temp.querySelector('ol'));
  },
  template = (v = {}) => {
    return `
<ol  style="--verticalOffset: ${v.height}">
  <li >height: <var>${v.height}</var></li>
  <li >width: <var>${v.width}</var></li>
  <li >flex-grow: <var>${v.flexGrow}</var></li>
  <li >flex-shrink: <var>${v.flexShrink}</var></li>
  <li >flex-basis: <var>${v.flexBasis}</var></li>
</ol>`
  }

document.querySelectorAll('.wrap > div').forEach(report);
*,
::before,
::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.wrap {
  display: flex;
  background: #ccc;
}

.wrap>div {
  position: relative;
}

.one {
  flex: 2;
  background: red;
}

.two {
  flex: 2;
  background: yellow;
}

.damn {
  flex: 1;
  background: blue;
}

.report {
  display: grid;
  gap: 0.25em;
  background-color: #fff;
  border: 1px solid #393;
  position: absolute;
  inset: auto 10%;
  list-style-type: none;
  translate: 0 calc(var(--verticalOffset) - 2vmin);
}

.report::before {
  content: "Computed CSS property-values:";
}

.report li {
  background-color: #eee;
  display: flex;
  justify-content: space-between;
  padding: 0.2em;
}

.report li:nth-child(even) {
  background-color: #fff;
}

var {
  color: #393;
  font-weight: 400;
}
<div class='wrap'>
  <div class='one'></div>
  <div class='two'></div>
  <div class='damn'>
    <vchessreplay>
      <moves>
        <move >
          <index>1.</index>d4
        </move>
        <comment></comment>
        <move >d5</move>
        <comment></comment>
        <move >
          <index>2.</index>Bf4
        </move>
        <comment></comment>
        <move >c5</move>
        <comment></comment>
        <move >
          <index>3.</index>e3
        </move>
        <comment></comment>
        <lines>
          <line->
            <move >
              <index>3...</index>cxd4
            </move>
            <comment></comment>
            <move >
              <index>4.</index>exd4
            </move>
            <comment></comment>
          </line->
          <line->
            <move >
              <index>3...</index>Qb6
            </move>
            <comment></comment>
            <move >
              <index>4.</index>Nc3
            </move>
            <comment></comment>
            <move >e6</move>
            <comment></comment>
            <move >
              <index>5.</index>Nf3
            </move>
            <comment></comment>
            <lines>
              <line->
                <move >
                  <index>5...</index>Be7
                </move>
                <comment> Hello world </comment>
                <move >
                  <index>6.</index>a5
                </move>
                <comment> What s up ok ok ok ook </comment>
                <move >Qd8</move>
                <comment></comment>
              </line->
              <line->
                <move >
                  <index>5...</index>c4
                </move>
                <comment></comment>
                <move >
                  <index>6.</index>b3
                </move>
                <comment></comment>
                <move >b5</move>
                <comment></comment>
                <move >
                  <index>7.</index>Rb1
                </move>
                <comment></comment>
                <lines>
                  <line->
                    <move >
                      <index>7...</index>Qa5
                    </move>
                    <comment></comment>
                    <lines>
                      <line->
                        <move >
                          <index>8.</index>Rxb7
                        </move>
                        <comment></comment>
                        <move >Qxc3</move>
                        <comment></comment>
                      </line->
                      <line->
                        <move >
                          <index>8.</index>Bxc4
                        </move>
                        <comment></comment>
                        <move >Qxc7</move>
                        <comment></comment>
                      </line->
                    </lines>
                  </line->
                  <line->
                    <move >
                      <index>7...</index>Qd7
                    </move>
                    <comment></comment>
                    <move >
                      <index>8.</index>Ne5
                    </move>
                    <comment></comment>
                  </line->
                </lines>
              </line->
            </lines>
          </line->
        </lines>
      </moves>
    </vchessreplay>
  </div>
</div>

JS Fiddle demo.

Though, honestly, for this level of control I'd – quite subjectively – prefer to use CSS Grid, given the level of control over track sizing:

const report = (node) => {
    let {
      width,
      height,
      flexGrow,
      flexShrink,
      flexBasis
    } = window.getComputedStyle(node, null),
      temp = document.createElement('div');
    temp.innerHTML = template({
      width,
      height,
      flexGrow,
      flexShrink,
      flexBasis
    });
    node.prepend(temp.querySelector('ol'));
  },
  template = (v = {}) => {
    return `
<ol  style="--verticalOffset: ${v.height}">
  <li >height: <var>${v.height}</var></li>
  <li >width: <var>${v.width}</var></li>
  <li >flex-grow: <var>${v.flexGrow}</var></li>
  <li >flex-shrink: <var>${v.flexShrink}</var></li>
  <li >flex-basis: <var>${v.flexBasis}</var></li>
</ol>`
  }

document.querySelectorAll('.wrap > div').forEach(report);
*,
::before,
::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.wrap {
  display: grid;
  grid-template-columns: 2fr 2fr 200px;
  background: #ccc;
}

.wrap > div {
  position: relative;
}

.one {
  background: red;
}

.two {
  background: yellow;
}

.damn {
  background: blue;
}

.report {
  display: grid;
  gap: 0.25em;
  background-color: #fff;
  border: 1px solid #393;
  position: absolute;
  inset: auto 10%;
  list-style-type: none;
  translate: 0 calc(var(--verticalOffset) - 2vmin);
}

.report::before {
  content: "Computed CSS property-values:";
}

.report li {
  background-color: #eee;
  display: flex;
  justify-content: space-between;
  padding: 0.2em;
}

.report li:nth-child(even) {
  background-color: #fff;
}

var {
  color: #393;
  font-weight: 400;
}
<div class='wrap'>
  <div class='one'></div>
  <div class='two'></div>
  <div class='damn'>
    <vchessreplay>
      <moves>
        <move >
          <index>1.</index>d4
        </move>
        <comment></comment>
        <move >d5</move>
        <comment></comment>
        <move >
          <index>2.</index>Bf4
        </move>
        <comment></comment>
        <move >c5</move>
        <comment></comment>
        <move >
          <index>3.</index>e3
        </move>
        <comment></comment>
        <lines>
          <line->
            <move >
              <index>3...</index>cxd4
            </move>
            <comment></comment>
            <move >
              <index>4.</index>exd4
            </move>
            <comment></comment>
          </line->
          <line->
            <move >
              <index>3...</index>Qb6
            </move>
            <comment></comment>
            <move >
              <index>4.</index>Nc3
            </move>
            <comment></comment>
            <move >e6</move>
            <comment></comment>
            <move >
              <index>5.</index>Nf3
            </move>
            <comment></comment>
            <lines>
              <line->
                <move >
                  <index>5...</index>Be7
                </move>
                <comment> Hello world </comment>
                <move >
                  <index>6.</index>a5
                </move>
                <comment> What s up ok ok ok ook </comment>
                <move >Qd8</move>
                <comment></comment>
              </line->
              <line->
                <move >
                  <index>5...</index>c4
                </move>
                <comment></comment>
                <move >
                  <index>6.</index>b3
                </move>
                <comment></comment>
                <move >b5</move>
                <comment></comment>
                <move >
                  <index>7.</index>Rb1
                </move>
                <comment></comment>
                <lines>
                  <line->
                    <move >
                      <index>7...</index>Qa5
                    </move>
                    <comment></comment>
                    <lines>
                      <line->
                        <move >
                          <index>8.</index>Rxb7
                        </move>
                        <comment></comment>
                        <move >Qxc3</move>
                        <comment></comment>
                      </line->
                      <line->
                        <move >
                          <index>8.</index>Bxc4
                        </move>
                        <comment></comment>
                        <move >Qxc7</move>
                        <comment></comment>
                      </line->
                    </lines>
                  </line->
                  <line->
                    <move >
                      <index>7...</index>Qd7
                    </move>
                    <comment></comment>
                    <move >
                      <index>8.</index>Ne5
                    </move>
                    <comment></comment>
                  </line->
                </lines>
              </line->
            </lines>
          </line->
        </lines>
      </moves>
    </vchessreplay>
  </div>
</div>

JS Fiddle demo.

But, effectively, your problem is largely solved by making your code readable. So my advice is (as always) choose readable over illegible (outside of minification, but in this specific case minification is not your friend).

References:

Bibliography:

CodePudding user response:

You cannot use <div> tag as empty tag.

.wrap {
display: flex;
background: #ccc;
}

.one {
flex: 1;
background: red;
}

.two {
flex: 1;
background: yellow;
}

.damn {
flex: 1;
background: blue;
}
<div class='wrap'>
  <div class='one'></div>
  <div class='two'></div>
  <div class='damn'>
    Lorem ipsum dolor sit amet hello world, Lorem ipsum dolor sit amet hello world.
  </div>
</div>

CodePudding user response:

Short answer

A div tag is not a self closed tag like a input. If you will change from <div /> to <div></div> then will work.

<div class='wrap'>
  <div class='one'></div>
  <div class='two'></div>
...

.wrap {
  display: flex;

  background: #ccc;
}

.one {
flex: 1;
  background: red;
}

.two {
flex: 1;
  background: yellow;
}

.damn {
flex: 1;
  background: blue;
}
<div class='wrap'>
  <div class='one'></div>
  <div class='two'></div>
  <div class='damn'>
    Lorem ipsum dolor sit amet hello world, Lorem ipsum dolor sit amet hello world.
  </div>
</div>

CodePudding user response:

.wrap {
  display: flex;

  background: #ccc;
}

.one {
flex: 1; 
  width: calc(100% / 3);
  background: red;
}

.two {
flex: 1;
  width: calc(100% / 3);
  background: yellow;
}

.damn {
flex: 1;
  width: calc(100% / 3);
  background: blue;
}
<div class='wrap'>
  <div class='one'></div>
  <div class='two'></div>
  <div class='damn'>
<vchessreplay><moves><move ><index>1.</index>d4</move><comment></comment><move >d5</move><comment></comment><move ><index>2.</index>Bf4</move><comment></comment><move >c5</move><comment></comment><move ><index>3.</index>e3</move><comment></comment><lines><line-><move ><index>3...</index>cxd4</move><comment></comment><move ><index>4.</index>exd4</move><comment></comment></line-><line-><move ><index>3...</index>Qb6</move><comment></comment><move ><index>4.</index>Nc3</move><comment></comment><move >e6</move><comment></comment><move ><index>5.</index>Nf3</move><comment></comment><lines><line-><move ><index>5...</index>Be7</move><comment> Hello world </comment><move ><index>6.</index>a5</move><comment> What s up ok ok ok ook </comment><move >Qd8</move><comment></comment></line-><line-><move ><index>5...</index>c4</move><comment></comment><move ><index>6.</index>b3</move><comment></comment><move >b5</move><comment></comment><move ><index>7.</index>Rb1</move><comment></comment><lines><line-><move ><index>7...</index>Qa5</move><comment></comment><lines><line-><move ><index>8.</index>Rxb7</move><comment></comment><move >Qxc3</move><comment></comment></line-><line-><move ><index>8.</index>Bxc4</move><comment></comment><move >Qxc7</move><comment></comment></line-></lines></line-><line-><move ><index>7...</index>Qd7</move><comment></comment><move ><index>8.</index>Ne5</move><comment></comment></line-></lines></line-></lines></line-></lines></moves></vchessreplay>
  </div>
</div>

use in calc() to set width of all div

CSS

width: calc(100% / 3); // width: 33.3333%

Edit code

You can try this css

.wrap {
    display: flex;
    background: #ccc;
    line-break: anywhere;
}
  • Related