Gregor Voinov
Gregor Voinov

Reputation: 2263

Stretch a svg-element to full height of a flex container

I have a container with display: flex. At both corners a svg-element should stretch to the full height of the container. The Height of the container depends on how much text is in the element.

In FF and Chrome it works perfect, but IE makes the svg always 150px height. I can't give the svg a fixed size, because it should stretch with the element if the text becomes multiline and the element grows.

I have done a codepen here

.flag-header {
  display: flex;
  max-width: 80%;
  position: relative;
}

.flag-header__headline {
  background-color: #bf0b1c;
  padding: 10px 0;
  color: white;
  font: 900 24px/120% Verdana;
  text-transform: uppercase;
}

.flag-header__corner {
  width: 30px;
}

.flag-header__corner-shape {
  height: 100%;
  width: 30px;
  fill: #bf0b1c;
}
<div class="flag-header">
  <div class="flag-header__corner">
    <svg class="flag-header__corner-shape" id="Layer_1" xmlns="http://www.w3.org/2000/svg" data-name="Layer 1" viewBox="0 0 22.11 30" preserveAspectRatio="none">
        <polygon class="cls-1" points="22.11 30 0 30 10 15 0 0 22.11 0 22.11 30"/>
            </svg>
  </div>
  <p class="flag-header__headline">sdfgsdgfsdgf sfasd fasdf asdfasdf</p>
  <div class="flag-header__corner">
    <svg class="flag-header__corner-shape" id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22.11 30" preserveAspectRatio="none">
            <polygon class="cls-1" points="0 30 22.11 30 12.11 15 22.11 0 0 0 0 30"/>
            </svg>
  </div>
</div>

Upvotes: 6

Views: 964

Answers (1)

OXiGEN
OXiGEN

Reputation: 2409

Not an answer. At best a hack. Just more observations into this unexpected behavior. Perhaps it's a bug.

Removing the svg wrapper and removing height: 100% from the svg has the same effect. (Closer to the layout I'm trying to debug. Good to know the wrapper OP started with makes no difference and I can avoid an unnecessary element.)

.flag-header {
  display: flex;
  max-width: 80%;
  position: relative;
}

.flag-header__headline {
  background-color: #bf0b1c;
  padding: 10px 0;
  color: white;
  font: 900 24px/120% Verdana;
  text-transform: uppercase;
}

.flag-header__corner-shape {
  width: 30px;
  fill: #bf0b1c;
}
<div class="flag-header">
  <svg class="flag-header__corner-shape" id="Layer_1" xmlns="http://www.w3.org/2000/svg" data-name="Layer 1" viewBox="0 0 22.11 30" preserveAspectRatio="none">
        <polygon class="cls-1" points="22.11 30 0 30 10 15 0 0 22.11 0 22.11 30"/>
            </svg>
  <p class="flag-header__headline">sdfgsdgfsdgf sfasd fasdf asdfasdf</p>
  <svg class="flag-header__corner-shape" id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22.11 30" preserveAspectRatio="none">
            <polygon class="cls-1" points="0 30 22.11 30 12.11 15 22.11 0 0 0 0 30"/>
            </svg>
</div>

A hack by inverting the variable height element's padding with negative margins on the variable element and the svg elements.

.flag-header {
  display: flex;
  max-width: 80%;
  position: relative;
  border: 1px solid black;
}

.flag-header__headline {
  background-color: #bf0b1c;
  padding: 10px 0;
  margin: -10px 0;
  color: white;
  font: 900 24px/120% Verdana;
  text-transform: uppercase;
}

.flag-header__corner-shape {
  width: 30px;
  fill: #bf0b1c;
  margin: -10px 0;
}
<div class="flag-header">
  <svg class="flag-header__corner-shape" id="Layer_1" xmlns="http://www.w3.org/2000/svg" data-name="Layer 1" viewBox="0 0 22.11 30" preserveAspectRatio="none">
        <polygon class="cls-1" points="22.11 30 0 30 10 15 0 0 22.11 0 22.11 30"/>
            </svg>
  <p class="flag-header__headline">sdfgsdgfsdgf sfasd fasdf asdfasdf</p>
  <svg class="flag-header__corner-shape" id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22.11 30" preserveAspectRatio="none">
            <polygon class="cls-1" points="0 30 22.11 30 12.11 15 22.11 0 0 0 0 30"/>
            </svg>
</div>

The hack falls apart without the arbitrary padding and margins. This implies that neither of those properties by themselves cause the issue, nor they can fix the issue by themselves, but they can fix it by working together to negate each other...

.flag-header {
  display: flex;
  max-width: 80%;
  position: relative;
  border: 1px solid black;
}

.flag-header__headline {
  background-color: #bf0b1c;
  color: white;
  font: 900 24px/120% Verdana;
  text-transform: uppercase;
}

.flag-header__corner-shape {
  width: 30px;
  fill: #bf0b1c;
}
<div class="flag-header">
  <svg class="flag-header__corner-shape" id="Layer_1" xmlns="http://www.w3.org/2000/svg" data-name="Layer 1" viewBox="0 0 22.11 30" preserveAspectRatio="none">
        <polygon class="cls-1" points="22.11 30 0 30 10 15 0 0 22.11 0 22.11 30"/>
            </svg>
  <p class="flag-header__headline">sdfgsdgfsdgf sfasd fasdf asdfasdf</p>
  <svg class="flag-header__corner-shape" id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22.11 30" preserveAspectRatio="none">
            <polygon class="cls-1" points="0 30 22.11 30 12.11 15 22.11 0 0 0 0 30"/>
            </svg>
</div>

Converting to grid doesn't fix anything. Even the hack stops working. Mess with height and width in the svg element and there are some very odd results.

.flag-header {
  display: grid;
  max-width: 80%;
  position: relative;
  grid-template-columns: 30px auto 30px;
  border: 1px solid black;
}

.flag-header__headline {
  background-color: #bf0b1c;
  padding: 10px 0;
  color: white;
  font: 900 24px/120% Verdana;
  text-transform: uppercase;
}

.flag-header__corner-shape {
  fill: #bf0b1c;
}
<div class="flag-header">
  <svg class="flag-header__corner-shape" id="Layer_1" xmlns="http://www.w3.org/2000/svg" data-name="Layer 1" viewBox="0 0 22.11 30" preserveAspectRatio="none">
        <polygon class="cls-1" points="22.11 30 0 30 10 15 0 0 22.11 0 22.11 30"/>
            </svg>
  <p class="flag-header__headline">sdfgsdgfsdgf sfasd fasdf asdfasdf</p>
  <svg class="flag-header__corner-shape" id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22.11 30" preserveAspectRatio="none">
            <polygon class="cls-1" points="0 30 22.11 30 12.11 15 22.11 0 0 0 0 30"/>
            </svg>
</div>

Converting to table doesn't fix anything. The height value in the svg element is irrelevant. Removing the height has an effect, though not what we want.

.flag-header {
  display: flex;
  max-width: 80%;
  position: relative;
  border-collapse: collapse;
  border-spacing: 0;
}

td {
  padding: 0;
}

.flag-header__headline {
  background-color: #bf0b1c;
  padding: 10px 0;
  color: white;
  font: 900 24px/120% Verdana;
  text-transform: uppercase;
}

.flag-header__corner-shape {
  width: 30px;
  fill: #bf0b1c;
  height: 100%;
}
<table class="flag-header">
  <tbody>
    <tr>
      <td>
        <svg class="flag-header__corner-shape" id="Layer_1" xmlns="http://www.w3.org/2000/svg" data-name="Layer 1" viewBox="0 0 22.11 30" preserveAspectRatio="none">
        <polygon class="cls-1" points="22.11 30 0 30 10 15 0 0 22.11 0 22.11 30"/>
            </svg>
      </td>
      <td>
        <p class="flag-header__headline">sdfgsdgfsdgf sfasd fasdf asdfasdf</p>
      </td>
      <td>
        <svg class="flag-header__corner-shape" id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22.11 30" preserveAspectRatio="none">
            <polygon class="cls-1" points="0 30 22.11 30 12.11 15 22.11 0 0 0 0 30"/>
            </td>
            </svg>
    </tr>
  </tbody>
</table>

Converting to pseudo-elements doesn't fix it. Lost CSS styling on the base64 encoded version of the raw SVG. That could be worked around with refs to a .svg file instead or inline CSS styles.

Thanks to: https://stackoverflow.com/a/32046349/2578125

.flag-header {
  display: flex;
  max-width: 80%;
  position: relative;
}

.flag-header__headline {
  background-color: #bf0b1c;
  padding: 10px 0;
  color: white;
  font: 900 24px/120% Verdana;
  text-transform: uppercase;
}

.flag-header::before,
.flag-header::after {
  width: 30px;
  fill: #bf0b1c;
  content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 22.11 30' preserveAspectRatio='none'%3E%3Cpolygon points='22.11 30 0 30 10 15 0 0 22.11 0 22.11 30'/%3E%3C/svg%3E");
}

.flag-header::after {
  content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 22.11 30' preserveAspectRatio='none'%3E%3Cpolygon points='0 30 22.11 30 12.11 15 22.11 0 0 0 0 30'/%3E%3C/svg%3E");
}
<div class="flag-header">
  <p class="flag-header__headline">sdfgsdgfsdgf sfasd fasdf asdfasdf</p>
</div>

Trying to merge the approach by @Alexei Zababurin with the OP's objectives. What works with such genius elegance for Alexei turns into a misshapen monstrosity here... The overrides are the only way to even show some of the content.

Ok, time to put this white whale to bed for a while before I completely lose my mind. May smarter and braver men prevail. Godspeed!

.flag-header {
  max-width: 80%;
  background-color: #bf0b1c;
  padding: 10px 0;
  color: white;
  font: 900 24px/120% Verdana;
  text-transform: uppercase;
  position: relative;
  z-index: 1;
  overflow: hidden;
  margin: 0 30px;
  overflow: initial;
}

.flag-header::before,
.flag-header::after {
  width: 30px;
  fill: #bf0b1c;
  display: inline-block;
  margin: 0 0 0 -100%;
  margin: 0 0 0 -30px;
  content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 22.11 30' preserveAspectRatio='none'%3E%3Cpolygon points='22.11 30 0 30 10 15 0 0 22.11 0 22.11 30'/%3E%3C/svg%3E");
}

.flag-header::after {
  margin: 0 -100% 0 0;
  margin: 0 -30px 0 0;
  content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 22.11 30' preserveAspectRatio='none'%3E%3Cpolygon points='0 30 22.11 30 12.11 15 22.11 0 0 0 0 30'/%3E%3C/svg%3E");
}
<div class="flag-header">sdfgsdgfsdgf sfasd fasdf asdfasdf
</div>

Upvotes: 1

Related Questions