How to make inline SVG 100% of parent container

391 views Asked by At

I'm trying to make an inline SVG scale to the width of the parent element. I feel like the circle elements are causing me the issue, but I'm unsure what I should be changing to achieve it.

I have set the container to 300x300px, I have set the viewBox to "0 0 300 300". I assume I have to set the r, cx, and cy to half those? to which I have set to "150" but the circle is now getting cut off.

I have been going round in circles (excuse the pun) changing dimensions but no luck.

Your help will be greatly appreciated.

Please find a link to my codepen: https://codepen.io/MayhemBliz/pen/NWyNGxj

function circle() {
  const progressRing = document.querySelector('.progress-ring');
  const circle = document.querySelector('.progress-ring__bar');
  const r = circle.getAttribute('r');
  const percent = progressRing.dataset.percent;

  const c = Math.PI * r * 2;
  const pct = ((0 - percent) / 100) * c;

  circle.style.strokeDashoffset = pct;
  //const percentageText = document.querySelector('.percentage');
  //percentageText.textContent = percent + "%";
}
window.addEventListener('load', circle);
.progress-ring {
  width: 300px;
  height: 300px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto;
}

.progress-ring__svg {
  /*transform: rotate(-90deg);*/
}

.progress-ring__bar-bg, .progress-ring__bar  {
  stroke-dashoffset: 0;
  transition: stroke-dashoffset 1s linear;
  stroke: #FF9F1E;
  stroke-width: 1em;
}

.progress-ring__bar {
  stroke: #666;
}

.percentage {
  position: absolute;
  font-size: 2.5rem;
  font-weight: bold;
}
<div class="progress-ring" data-percent="80">
  <svg class="progress-ring__svg" viewBox="0 0 300 300" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <circle class="progress-ring__bar-bg" r="150" cx="150" cy="150" fill="transparent" stroke-dasharray="565.48" stroke-dashoffset="0"></circle>
    <circle class="progress-ring__bar" r="150" cx="150" cy="150" fill="transparent" stroke-dasharray="565.48" stroke-dashoffset="0"></circle>
  </svg>
  <span class="percentage">80%</span>
</div>

1

There are 1 answers

0
herrstrietzel On

To avoid overflow you could use percentage based values for stroke-width and r (radius) like so:

<circle r="47.5%" cx="50%" cy="50%" />

or a pixel based approximation like

<circle r="142" cx="150" cy="150" />

function circle() {

const progressRing = document.querySelector('.progress-ring');
const circle = document.querySelector('.progress-ring__bar');
const r = circle.getAttribute('r');
const percent = progressRing.dataset.percent;

const c = Math.PI * r * 2;
const pct = ((0 - percent) / 100) * c;

circle.style.strokeDashoffset = pct;
  
//const percentageText = document.querySelector('.percentage');
//percentageText.textContent = percent + "%";
  
}

window.addEventListener('load', circle);
.progress-ring {
  width: 300px;
  /*height: 300px;*/
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto;
  max-width:100%;
}

.progress-ring__svg {
  //width:100%;
  /*transform: rotate(-90deg);*/
}

.progress-ring__bar-bg, .progress-ring__bar  {
  stroke-dashoffset: 0;
  transition: stroke-dashoffset 1s linear;
  stroke: #FF9F1E;
  stroke-width: 5%;
}

.progress-ring__bar {
  stroke: #666;
}

.percentage {
  position: absolute;
  font-size: 2.5rem;
  font-weight: bold;
}

.resize{
  resize:both;
  overflow:auto;
  border: 1px solid #ccc;
  padding:1em;
}
<div class="resize">
<div class="progress-ring" data-percent="80">
  <svg class="progress-ring__svg" viewBox="0 0 300 300" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <circle class="progress-ring__bar-bg" r="47.5%" cx="50%" cy="50%" fill="transparent" stroke-dasharray="565.48" stroke-dashoffset="0"></circle>
    <circle class="progress-ring__bar" r="142" cx="150" cy="150" fill="transparent" stroke-dasharray="565.48" stroke-dashoffset="0"></circle>
      <text class="percentage" x="50%" y="50%" text-anchor="middle" dominant-baseline="middle" dy="2%">80%</text>

  </svg>
</div>
  </div>
<p>Resize me</p>

However, you might also use a <text> element instead of a <span> to keep the percentage text size relative to you svg boundary.