Setting “width: auto” inside a <div> with “display: flex; flex-direction: row” doesn't work

柔情痞子 提交于 2021-01-29 04:11:52

问题


I'm trying to place bunch of divs side by side, left to right. So I'm using a flexbox with direction set to row.

I want each of those divs to derive their height and width from the content inside, hence I have left their height and width to default.

Lastly, I want to use an svg as the background. For that, I'm using a grid container and placing both the svg and the div in the same column and row as suggested in this stackoverflow post. Im setting the height and width of the svg to 100% to ensure it fills the whole background.

When I combine everything together, though, the width is of the divs are not being set properly. The height of the div seems to be set by the content inside, but the width seems to always default to 300px. For the life of me, I cant figure out how this width is being calculated. If the content is wider than 300px, then everything works as expected. But the container never shrinks to fit if the content is smaller than 300px.

How can I makes sure the divs are always shrunk to fit? See the code sample below:

.top {
  padding: 20px;
  display: flex;
  flex-direction: row;
}

.grid-container {
  background-color: red;
  display: grid;
}

.svg {
  grid-column: 1;
  grid-row: 1;
  width: 100%;
  height: 100%;
}

.content {
  grid-column: 1;
  grid-row: 1;
  font-size: 100px;
}
This div has calculated width 300px for some reason
<div class="top">
  <div class="grid-container" key="1">
    <svg class="svg" viewBox="-10 -10 20 20" preserveAspectRatio="none">
      <polygon strokeWidth="0" fill="yellow" points="0,-10 10,0 0,10 -10,0" />
    </svg>
    <div class="content">
      ab
    </div>
  </div>
  <!-- more grid-containers -->
</div>

This works as expected
<div class="top">
  <div class="grid-container">
    <svg class="svg" viewBox="-10 -10 20 20" preserveAspectRatio="none">
      <polygon strokeWidth="0" fill="yellow" points="0,-10 10,0 0,10 -10,0" />
    </svg>
    <div class="content">
      abcdefghijkl
    </div>
  </div>
  <!-- more grid-containers -->
</div>

回答1:


There is a default width/height applied to SVG element creating this output. To avoid the issue make sure you set the attribute width/height to 0

.top {
  padding: 20px;
  display: flex;
  flex-direction: row;
}

.grid-container {
  background-color: red;
  display: grid;
}

.svg {
  grid-column: 1;
  grid-row: 1;
  width: 100%;
  height: 100%;
}

.content {
  grid-column: 1;
  grid-row: 1;
  font-size: 100px;
}
This div has calculated width 300px for some reason
<div class="top">
  <div class="grid-container" key="1">
    <svg class="svg" viewBox="-10 -10 20 20" preserveAspectRatio="none" width="0" height="0">
      <polygon strokeWidth="0" fill="yellow" points="0,-10 10,0 0,10 -10,0" />
    </svg>
    <div class="content">
      ab
    </div>
  </div>
  <!-- more grid-containers -->
</div>

This works as expected
<div class="top">
  <div class="grid-container">
    <svg class="svg" viewBox="-10 -10 20 20" preserveAspectRatio="none" width="0" height="0">
      <polygon strokeWidth="0" fill="yellow" points="0,-10 10,0 0,10 -10,0" />
    </svg>
    <div class="content">
      abcdefghijkl
    </div>
  </div>
  <!-- more grid-containers -->
</div>



回答2:


I was able to solve this by adding position: relative; to the .grid-container and position: absolute; to the svg and then giving the .content a z-index:1;

See here:

.top {
  padding: 20px;
  display: flex;
  flex-direction: row;
}

.grid-container {
  background-color: red;
  display: grid;
  width: auto;
  position: relative;
}

.svg {
  grid-column: 1;
  grid-row: 1;
  width: 100%;
  height: 100%;
  position: absolute;
}

.content {
  grid-column: 1;
  grid-row: 1;
  font-size: 100px;
  z-index:1;
}
This div has calculated width 300px for some reason
<div class="top">
  <div class="grid-container" key="1">
    <svg class="svg" viewBox="-10 -10 20 20" preserveAspectRatio="none">
      <polygon id="diamond" strokeWidth="0" fill="yellow" points="0,-10 10,0 0,10 -10,0" />
    </svg>
    <div class="content">
      ab
    </div>
  </div>
  <!-- more grid-containers -->
</div>

This works as expected
<div class="top">
  <div class="grid-container">
    <svg class="svg" viewBox="-10 -10 20 20" preserveAspectRatio="none">
      <polygon strokeWidth="0" fill="yellow" points="0,-10 10,0 0,10 -10,0" />
    </svg>
    <div class="content">
      abcdefghijkl
    </div>
  </div>
  <!-- more grid-containers -->
</div>



回答3:


You can try to use SVG as background image for the .grid-container (inline or linked), so you won't need to insert it into each single div. Importantly, the SVG must have preserveAspectRatio = 'none':

.top {
  padding: 20px;
  display: flex;
  flex-direction: row;
}

.grid-container {
  background-color: red;
  display: grid;
  background-image: 
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100%' height='100%' viewBox='-10 -10 20 20' preserveAspectRatio='none'> <polygon strokeWidth='0' fill='yellow' points='0,-10 10,0 0,10 -10,0'/> </svg>");
  background-repeat: no-repeat;
  background-size: cover;
}

.content {
  grid-column: 1;
  grid-row: 1;
  font-size: 100px;
}
<div class="top">
  <div class="grid-container" key="1">
    <div class="content">
      ab
    </div>
  </div>
  <!-- more grid-containers -->
</div>

<div class="top">
  <div class="grid-container">
    <div class="content">
      abcdefghijkl
    </div>
  </div>
  <!-- more grid-containers -->
</div>


来源:https://stackoverflow.com/questions/62367587/setting-width-auto-inside-a-div-with-display-flex-flex-direction-row-d

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!