SVG center text in circle

I'm trying to center text in a circle with svg.

the size of the text will be dynamic.

Thank's Avi

plunker

My code:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" style="shape-rendering:geometricPrecision; text-rendering:geometricPrecision; image-rendering:optimizeQuality; fill-rule:evenodd; clip-rule:evenodd" viewBox="0 0 500 500">


<g id="UrTavla">
<circle style="fill:url(#toning);stroke:#010101;stroke-width:1.6871;stroke-miterlimit:10;" cx="250" cy="250" r="245">


</circle>
<text x="50%" y="50%" stroke="#51c5cf" stroke-width="2px" dy=".3em"> Look, I’m centered!Look, I’m centered! </text>
</g>
</svg>
110839 次浏览

Add text-anchor="middle" to the text element.

Plunker

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" style="shape-rendering:geometricPrecision; text-rendering:geometricPrecision; image-rendering:optimizeQuality; fill-rule:evenodd; clip-rule:evenodd"
viewBox="0 0 500 500">
<g id="UrTavla">
<circle style="fill:url(#toning);stroke:#010101;stroke-width:1.6871;stroke-miterlimit:10;" cx="250" cy="250" r="245">
</circle>
<text x="50%" y="50%" text-anchor="middle" stroke="#51c5cf" stroke-width="2px" dy=".3em">Look, I’m centered!Look, I’m centered!</text>
</g>
</svg>

Maybe, could be useful also alignment-baseline="middle", with text-anchor="middle":

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" style="shape-rendering:geometricPrecision; text-rendering:geometricPrecision; image-rendering:optimizeQuality; fill-rule:evenodd; clip-rule:evenodd" viewBox="0 0 500 500">


<g id="UrTavla">
<circle style="fill:url(#toning);stroke:#010101;stroke-width:1.6871;stroke-miterlimit:10;" cx="250" cy="250" r="245" /> <!--self-closing tag-->


<text x="50%" y="50%" stroke="#51c5cf" stroke-width="2px" dy=".3em" text-anchor="middle" alignment-baseline="middle"> Look, I’m centered!Look, I’m centered! </text>
</g>
</svg>

Here a good resource: http://apike.ca/prog_svg_text_style.html

Cheers

The solution proposed and accepted is INVALID when you want to draw a circle that is not centered on container !

Using x="50%" y="50%" on text tag works only when SVG element contains a circle that is centered on viewPort.

If you want to draw 3 circles, you must also change (x,y) text coordinates so that they are equal to (cx,cy) circle coordinates has done in following example

As proposed by random, I have added alignment-baseline="middle" for first circle in code snippet only so you can see that for Label text is now perfectly aligned (vertically).

<svg height="350" width="350">
<circle cx="110" cy="110" r="100"
stroke="red"
stroke-width="3"
fill="none"
/>
<text x="110" y="110"
text-anchor="middle"
stroke="red"
stroke-width="1px"
alignment-baseline="middle"
> Label
</text>
<circle cx="240" cy="110" r="100"
stroke="blue"
stroke-width="3"
fill="none"
/>
<text x="240" y="110"
text-anchor="middle"
stroke="blue"
stroke-width="1px"
> Ticket
</text>
<circle cx="170" cy="240" r="100"
stroke="green"
stroke-width="3"
fill="none"
/>
<text x="170" y="240"
text-anchor="middle"
stroke="green"
stroke-width="1px"
> Vecto
</text>
</svg>

Just for the fun, I have put code with 3 circles to select each parts. Just click on it !

    function setReadableCode()
{
var circLabel = document.getElementById('circLabel');
var circTicket = document.getElementById('circTicket');
var circVecto = document.getElementById('circVecto');
var interLabelTicket = document.getElementById('interLabelTicket');
var interTicketVecto = document.getElementById('interTicketVecto');
var interVectoLabel = document.getElementById('interVectoLabel');
var interLabelTicketVecto = document.getElementById('interLabelTicketVecto');
}


function clickCircle(sCircle, sInter2a, sInter2b, sInter3)
{
var circ = document.getElementById(sCircle);
var inter2a = document.getElementById(sInter2a);
var inter2b = document.getElementById(sInter2b);
var inter3 = document.getElementById(sInter3);


var sColor = '';


if (circ.style.fill == '' || circ.style.fill == 'white')
{
sColor = 'yellow';
}
else
{
sColor = 'white';
}


circ.style.fill = sColor;
inter2a.style.fill = sColor;
inter2b.style.fill = sColor;
inter3.style.fill = sColor;


setReadableCode();
}


function clickCircLabel() {
clickCircle('circLabel', 'interLabelTicket', 'interVectoLabel', 'interLabelTicketVecto');
}


function clickCircTicket() {
clickCircle('circTicket', 'interLabelTicket', 'interTicketVecto', 'interLabelTicketVecto');
}


function clickCircVecto() {
clickCircle('circVecto', 'interVectoLabel', 'interTicketVecto', 'interLabelTicketVecto');
}


function clickIntersection2(sInter2, sInter3) {
var inter2 = document.getElementById(sInter2);
var inter3 = document.getElementById(sInter3);
var sColor = '';


if (inter2.style.fill == '' || inter2.style.fill == 'white') {
sColor = 'yellow';
}
else {
sColor = 'white';
}


inter2.style.fill = sColor;
inter3.style.fill = sColor;


setReadableCode();
}


function clickInterLabelTicket() {
clickIntersection2('interLabelTicket', 'interLabelTicketVecto');
}


function clickInterTicketVecto() {
clickIntersection2('interTicketVecto', 'interLabelTicketVecto');
}


function clickInterVectoLabel() {
clickIntersection2('interVectoLabel', 'interLabelTicketVecto');
}


function clickInterLabelTicketVecto() {
var inter = document.getElementById('interLabelTicketVecto');
var sColor = '';


if (inter.style.fill == '' || inter.style.fill == 'white') {
sColor = 'yellow';
}
else {
sColor = 'white';
}


inter.style.fill = sColor;
setReadableCode();
}
text
{
font-family:Arial;
}
<svg height="350" width="350">
<circle id="circLabel" cx="110" cy="110" r="100" stroke="red" stroke-width="0" fill="white" onclick="clickCircLabel();"/>
<text x="60" y="110" text-anchor="middle" stroke="red" stroke-width="1px" onclick="clickCircLabel();">Label</text>
<circle id="circTicket" cx="210" cy="110" r="100" stroke="blue" stroke-width="0" fill="yellow" onclick="clickCircTicket();"/>
<text x="260" y="110" text-anchor="middle" stroke="blue" stroke-width="1px" onclick="clickCircTicket();">Ticket</text>
<circle id="circVecto" cx="160" cy="196.602541" r="100" stroke="green" stroke-width="0" fill="white" onclick="clickCircVecto();" />
<text x="160" y="240" text-anchor="middle" stroke="green" stroke-width="1px" onclick="clickCircVecto();">Vecto</text>
<path id="interLabelTicket"
d="M 160 23.397460 a100,100 0 0,0 0,173.205081 a100,100 0 0,0 0,-173.205081 z"
fill="white"
stroke-width="3"
onclick="clickInterLabelTicket();"
/>


<path id="interVectoLabel"
d="M 60 196.602541 a100,100 0 0,0 150,-86.602540 a100,100 0 0,0 -150,86.602540 z"
fill="white"
stroke-width="3"
onclick="clickInterVectoLabel();"
/>


<path id="interTicketVecto"
d="M 260 196.602541 a100,100 0 0,0 -150,-86.602540 a100,100 0 0,0 150,86.602540 z"
fill="white"
stroke-width="3"
onclick="clickInterTicketVecto();"
/>


<path id="interLabelTicketVecto"
d="M 110 110 a100,100 0 0,1 100,0 a100,100 0 0,1 -50,86.602540 a100,100 0 0,1 -50,-86.602540 z"
fill="none"
stroke-width="3"
onclick="clickInterLabelTicketVecto();"
/>


<circle cx="110" cy="110" r="100" stroke="red" stroke-width="3" fill="none" />
<circle cx="210" cy="110" r="100" stroke="blue" stroke-width="3" fill="none" />
<circle cx="160" cy="196.602541" r="100" stroke="green" stroke-width="3" fill="none"/>


</svg>

A simpler solution that works with non-centered circles is to put circles and texts inside translated groups.

That way you don't need to repeat the coordinates on the text.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Centered texts</title>
</head>


<body ng-controller="MainCtrl">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500">
<g transform="translate(300, 300)" >
<circle fill="none" stroke="black" stroke-width="1px" r="120"/>
<text stroke="blue" stroke-width="1px" text-anchor="middle" alignment-baseline="central">Look, I’m centered!</text>
</g>
      

<g transform="translate(150, 150)" >
<circle fill="none" stroke="black" stroke-width="1px" r="120"/>
<text stroke="blue" stroke-width="1px" text-anchor="middle" alignment-baseline="central">Look, I’m also centered!</text>
</g>
</svg>
</body>
</html>

it is super easy to make text center in SVG circle.

<svg height="300" width="300">
<circle cx="120" cy="120" r="30%" fill="#117da9" />
<text x="50" y="120" fill="white">Center Text in SVG Circle</text>
</svg>

All you need to do is change <text> tag x and y values until the given text align in the center of the circle. For example, here x and y values are x="50" y="120"

The behaviors are not consistent across browsers using alignment-baseline="central". Notably, Chrome will position correctly but Firefox will not. If you use dominant-baseline="central" it will appear correctly in both.

      <svg viewBox="0 0 500 500" role="img" xmlns="http://www.w3.org/2000/svg">
<g id="myid">
<circle stroke="darkgray" stroke-width="1px" fill="lightgray"  cx="250" cy="250" r="245"/>
<text style="font: bold 10rem sans-serif;" text-anchor="middle" dominant-baseline="central" x="50%" y="50%">Centered</text>
</g>
</svg>