2018 / 03 / 09
2022 / 08 / 02
Fluid SVGs with Vue 3

Have your SVGs adjust to their parents width.

vue 3

A fluid SVG is one that can grow as far as its parent allows it to.
The trick lies in how we define the <svg> element.

Only set the viewBox attribute, but don’t set a height nor width on it.
Thus, it’ll preserve its aspect ratio, growing and shrinking accordingly.

This is the svg component src/components/svg/SvgBox.vue:

  <svg viewBox="0 0 1000 1000" class="bg-stone-300">
      class="fill-amber-600 stroke-black stroke-2"

This is the container src/components/svg/SvgWrapper.vue:

<script lang="ts" setup>
import { computed } from 'vue'

const props = defineProps<{
  width: string

const widthPercent = computed(() => `${props.width}%`)

  <div class="svg-wrapper">

<style scoped>
.svg-wrapper {
  width: v-bind('widthPercent');

It just contains a <div> with a configurable width — that’s how the slider controls it.
The SvgBox will shrink and grow as much as permitted by the wrapper’s width.

The code for the mini-demo above is just this:

<script setup lang="ts">
import { ref } from 'vue'

import SvgBox from '@/components/svg/SvgBox.vue'
import SvgWrapper from '@/components/svg/SvgWrapper.vue'

const width = ref('50')

  <div>Current parent <strong>div</strong> width: {{ width }}%</div>

  <input v-model="width" type="range" />

  <SvgWrapper :width="width">

That’s it! :grin: