Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Centering responsive svg circle in container

Tags:

html

css

svg

Test page

Markup:

<svg viewBox="0 0 400 400"  preserveAspectRatio="xMinYMin meet">
    <g>
        <circle r="70" class="circle-back" />
    </g>
</svg>

CSS

.doughnutChart{
    text-align:center;
    padding:50% 1em 0;
    position: relative;
    overflow: hidden;

    > svg{
        position: absolute;
        top: 0;
        left:0; right:0;
        margin: auto;

        g{ transform:rotate(270deg) translate(-88px, 200px); }
    }

    circle{ fill: none; }
    .circle-back { stroke:#EEE; stroke-width: 5px; }
}

As you can see in the test page, I am trying to position a responsive circle with some radius, and I want it to position itself in the middle of the container, regardless the width of the container. It would be even better if the circle also fit itself to the height of the container.

There seem to be a problem with css translate using percentages on the g element, which prevents me from just doing translate(-50%, -50%)


This is a very simplified version of what I have, since in my code it's a doughnut chart, this is why it has this rotate transform to it

like image 851
vsync Avatar asked Oct 14 '15 20:10

vsync


1 Answers

If you want the SVG to be the size of the circle you need to set the viewbox to twice the radius and determine a center point.

The circle is centered in cx , cy and has a radius of r. cx, cy and r are attributes of the element.

svg {
  height: 100px;
  border: 1px solid green;
}
circle {
  fill: none;
}
.circle-back {
  stroke: #EEE;
  stroke-width: 5px;
}
<svg viewBox="0 0 140 140" preserveAspectRatio="xMinYMin meet">
  <g>
    <circle r="70" cx="50%" cy="50%" class="circle-back" />
  </g>
</svg>

You always need to determine the center of the circle using cx and cy which will default to 0,0 (left top) if not stated.

Alternatively, for a viewbox-independent centered circle you could use a % radius.

svg {
  height: 100px;
  border: 1px solid plum;
}
circle {
  fill: none;
}
.circle-back {
  stroke: #EEE;
  stroke-width: 5px;
}
<svg viewBox="0 0 140 140" preserveAspectRatio="xMinYMin meet">
  <g>
    <circle r="50%" cx="50%" cy="50%" class="circle-back" />
  </g>
</svg>

In your original code.

svg {
  height: 100px;
  border: 1px solid red;
}
circle {
  fill: none;
}
.circle-back {
  stroke: #EEE;
  stroke-width: 5px;
}
<svg viewBox="0 0 400 400" preserveAspectRatio="xMinYMin meet">
  <g>
    <circle r="70" cx="200" cy="200" class="circle-back" />
  </g>
</svg>

See the difference?

Reference Link with tutorials & video

like image 194
Paulie_D Avatar answered Oct 03 '22 08:10

Paulie_D