Harry
Harry

Reputation: 4835

Change SVG viewBox size from CSS without javascript

I have a very simple block of SVG text created using only HTML and CSS:

<div class="wrapper logo">
  <svg viewBox="0 0 225 80" class="logo-prompt">
    <text x="0" y="65">first</text>
  </svg>
  <svg viewBox="0 0 45 80" class="logo-category">
    <text x="0" y="65">test</text>
  </svg>
  <svg viewBox="0 0 45 80" class="logo-cursor">
    <text x="0" y="65">_</text>
  </svg>
</div>
.wrapper {
  display: flex;
  align-items: center;
  height: 100%;
  padding: 0.15em;
}

svg {
  height: 100%;
  fill: white;
}

This works nicely, except that the middle text element (currently <text>test</text>) needs to be able to change length by altering the viewBox. I'm using a monospace font so I know that every character adds 45 to thew viewBox horizontal length, thus it should be as simple as setting viewBox="0 0 180 80" for the 4 character example.

I have tried using transform: scaleX(4); as suggested elsewhere on Stack Overflow, but this does not work as it simply stretches the svg, rather than altering the viewBox and thus the aspect ratio.

My difficulty is that I don't know the sizes up-front, so I want to be able to do this with css variables, which I thought would be straightforward, but seems that setting `viewBox: '0 0 180 80' is not valid css.

Is there a way to set the viewBox size in css?

Upvotes: 1

Views: 3416

Answers (1)

ccprog
ccprog

Reputation: 21876

I can see two approaches to solve this. The first one is to have no viewBox attribute at all.

<svg>
  <text x="0" y="65">test</text>
</svg>

svg {
  width: calc(var(--letter-count) * 40px);
  height: 80px;
}

This comes at the price of the SVG no longer being responsive.

The second solution looks a bit hacky, but works:

<svg viewBox="0 0 45 80" preserveAspectRatio="xMinYMid meet">
  <text x="0" y="65">test</text>
</svg>

svg {
  overflow: visible;
  width: calc(var(--letter-width) * var(--letter-count));;
  height: 100%;
}

The preserveAspectRatio value takes care for the text to start always at the left side. You would need to set width to a value that leaves enough space to the right for the text to run into. If the SVG is scaled, your CSS would have to adapt the --letter-width variable accordingly.

Upvotes: 3

Related Questions