When it comes to text alignment in SVG, the process works differently compared to HTML and CSS. Unlike the box model in CSS where dimensions are set and alignment is straightforward using properties like text-align: center
, working with text alignment in SVG involves defining starting coordinates from which the text line expands.
The <svg:text>
element uses starting coordinates to determine the expansion direction of the text line. The text-anchor
attribute plays a crucial role in controlling this expansion. For instance, setting the value to center
ensures that the text expands evenly on both sides, with the initial anchor point aligned at the middle of the bounding box width for horizontal writing systems. Check out an informative answer demonstrating the use of text-anchor
to center text in SVG here: . Moreover, unlike HTML, SVG does not support CSS position properties such as left/top; instead, it relies on x/y coordinates without margins or other box model features.
To achieve centered text in your code, adding the attribute text-anchor="middle"
and adjusting the x
coordinate position would result in properly aligned text. It's recommended to use bare <text>
elements rather than <tspan>
elements when aligning text in SVG. Shifting tspan
with dx
/dy
attributes can lead to unbalanced centering due to spaces inherited from parent <text>
. Additionally, using dominant-baseline
="central"
(or simply middle
for horizontal writing) facilitates easier positioning by moving the anchor point to the "center line" rather than the base line. Utilizing the dy
attribute to adjust the text lines' vertical spacing can help achieve the desired centering effect:
<svg viewBox="0 0 800 200" text-anchor="middle" dominant-baseline="central" font-size="100">
<!-- Outline and diagonals with center point for illustration: -->
<path d="M0,0h800v200h-800zl800,200m0 -200L0,200" fill="#FC9" stroke-width="1" stroke="rgba(0,0,0,0.3)"></path>
<circle cx="50%" cy="50%" r="10" fill="red"></circle>
<!-- Centered text: -->
<text x="50%" y="50%" fill="rgba(0,0,0,0.3)">So</text>
<!-- Shifted up and down: -->
<text x="50%" y="50%" dy="-0.5em">So</text>
<text x="50%" y="50%" dy="+0.5em">Food</text>
</svg>
(On a side note: achieving clipping effects solely through CSS can be done using background-clip: text
. Here's an example showcasing a rough variation of your design in Chrome browser, featuring animated text backgrounds without shadows. Unfortunately, adding shadows may require additional elements or attributes. This styling should work across browsers supporting background-clip.)
div {
display: flex;
flex-direction: column;
align-items: center;
font-size: 30vh;
line-height: 30vh;
font-weight: bold;
font-family: Impact;
}
span {
color: #fff;
background-color: #000;
width: 100%;
text-align: center;
}
@supports (-webkit-text-fill-color: transparent) and (-webkit-background-clip: text) {
span {
-webkit-text-fill-color: transparent;
-webkit-background-clip: text;
animation: 2s wohoo infinite alternate cubic-bezier(1,0,1,1);
background-position: 0 0;
background-size: 100% 100%;
background-color: transparent;
background-image: linear-gradient(
to right,
#f2385a 0,
#f2385a 20%,
#f5a503 0,
#f5a503 40%,
#e9f1df 0,
#e9f1df 60%,
#56d9cd 0,
#56d9cd 80%,
#3aa1bf 0,
#3aa1bf 100%
);
background-repeat: no-repeat;
transform-origin: center center;
}
}
@keyframes wohoo {
from {
background-size: 0 100%;
background-position: -5vh 0;
transform: scale(0.7);
}
50% {
transform: scale(0.7);
}
90% {
transform: scale(0.9);
}
to {
background-size: 500% 100%;
background-position: 0vh 0;
transform: scale(0.9)
}
}
html,body{margin:0;overflow:hidden;}
body {
background-color: #1d1f20;
color: snow;
display: flex;
flex-direction: row;
justify-content: center;
width: 100%;
}
<div>
<span>Baz</span>
<span>Gazonk</span>
<span>Qux</span>
</div>