herman
herman

Reputation: 12305

SVG with dynamic height without scaling

The following code shows an SVG whose height depends on the height of another element:

https://codepen.io/HermanBovens/pen/aLjBGE

HTML

<div class="root">
  <div >
    <div>This</div>
    <div>content</div>
    <div>determines</div>
    <div>the</div>
    <div>height</div>
    <div>of</div>
    <div>the</div>
    <div>SVG</div>
  </div>
  <svg width="50px" viewBox="0 0 20 20" preserveAspectRatio = "none slice">
    <!-- I want do draw a down arrow here that spans the whole height, but only the length of the line should be variable, the arrow should not scale -->
    <line x1="10" y1="0" x2="10" y2="20" stroke="black" stroke-width="2"/>
    <line x1="0" y1="15" x2="10" y2="20" stroke="black" stroke-width="1"/>
    <line x1="20" y1="15" x2="10" y2="20" stroke="black" stroke-width="1"/>
  </svg>
</div>

CSS

.root {
  display: flex;
  align-items: stretch;
}


svg {
  background: lightblue;
}

How can the code be adapted so that the line of the arrow gets longer as the content on the left gets longer, but without the head being stretched?

Upvotes: 1

Views: 1119

Answers (2)

Paul LeBeau
Paul LeBeau

Reputation: 101830

You can use the SVG <use> trick.

You define an arrowhead that is positioned with its point at y=0. Then reference it with a <use> width y="100%" so it gets repositioned at the maximum Y (bottom) of the SVG.

.root {
  display: flex;
}


svg {
  background: lightblue;
}
<div class="root">
  <div >
    <div>This</div>
    <div>content</div>
    <div>determines</div>
    <div>the</div>
    <div>height</div>
    <div>of</div>
    <div>the</div>
    <div>SVG</div>
    <div>SVG</div>
    <div>SVG</div>
    <div>SVG</div>
    <div>SVG</div>
  </div>
  <svg width="50px">
    <defs>
      <polyline id="arrow-head"
                points="3,-15, 25,-2.5 47,-15"
                fill="none" stroke="black" stroke-width="5"/>
    </defs>
    <line x1="50%" y1="0" x2="50%" y2="100%"
          stroke="black" stroke-width="5" stroke-dasharray="10 5"/>
    <use y="100%" xlink:href="#arrow-head"/>
  </svg>
</div>

Upvotes: 2

herman
herman

Reputation: 12305

I guess the simplest way, following the principle of least surprise, would be to put the vertical line and the arrow head in separate SVG elements and overlay them.

To allow usage of a dashed stroke without scaling the dashes, I can use

vector-effect="non-scaling-stroke"

on the <line/> element.

Keeping the question open for potentially better suggestions.

Upvotes: 0

Related Questions