Fluid SVGs with Vue.js

Published on 2018/03/09

I really like going for fluid SVGs when doing data visualization.

Fluid SVGs are the ones that can extend on the horizontal axis as far as the parent allows it.
They preserve their aspect ratio, growing and shrinking accordingly to adjust themselves if their size ever changes.

The trick lies in how you define the <svg> element, specially its viewBox attribute.
Also, you shall not define height or width attributes on it.


Here is a single file component in Vue.js that will behave exactly like that.
Let’s name it src/components/FluidSvg.vue:

<template>
  <div>

    <svg :viewBox="viewBoxString">
      <rect
        class="my-square"
        :x="rect.x"
        :y="rect.y"
        :width="rect.width"
        :height="rect.height"
      ></rect>
    </svg>

  </div>
</template>

<script>
export default {
  name: 'FluidSvg',

  data () {
    return {
      svg: {
        width: 1000,
        height: 1000
      },
      rect: {
        x: 100,
        y: 100,
        width: 300,
        height: 300
      }
    }
  },

  computed: {
    viewBoxString () {
      return `0 0 ${this.svg.width} ${this.svg.height}`
    }
  }
}
</script>

<style>
svg {
  background-color: antiquewhite;
  border: 2px solid black;
}

.my-square {
  fill: white;
  stroke: red;
  stroke-width: 2;
}
</style>

Now, use it inside some other component like this:

<template>
  <div>
    <div class="example-1">
      <fluid-svg></fluid-svg>
    </div>

    <div class="example-2">
      <fluid-svg></fluid-svg>
    </div>

    <div class="example-3">
      <fluid-svg></fluid-svg>
    </div>
  </div>
</template>

<script>
import FluidSvg from '@/components/FluidSvg'

export default {
  name: 'HelloWorld',
  components: { FluidSvg },
}
</script>

<style>
.example-1 {
  width: 100px;
}

.example-2 {
  width: 200px;
}

.example-3 {
  width: 400px;
}
</style>

This is what you’ll see:

Fluid SVGs


— lt

Feedback & comments

Get in touch on Twitter

Or by good ol' email at adriandcs@gmail.com