ninjaas
ninjaas

Reputation: 337

CSS transform on SVG text element not working in Safari

Trying to position a battery indicator within a parent SVG.The SVG <svg viewBox="0 0 24 24"> element has a path for the battery and a text element showing the percentage.Its being positioned with a couple of css transforms and text attributes.The text is correctly positioned when opening in chrome/firefox but goes offshoot in safari.

<text 
    text-anchor="middle"
    dominant-baseline="middle"
    style="transform:translate(50%,98%) scale(.2);
    font:700 13px sans-serif;fill:#deba78"
    >24.2%</text>

Codepen https://codepen.io/niwsa/pen/rNNBKEg?editors=1000

Upvotes: 6

Views: 5023

Answers (2)

Robert Monfera
Robert Monfera

Reputation: 2147

Wrap the <text> element into a <g> element and apply the CSS transform on that, it happens to work currently even in Safari. This way, it's still CSS, so CSS transitions, animations, custom properties, selector based styling, continuous font scaling etc. work.

Upvotes: 9

enxaneta
enxaneta

Reputation: 33062

Instead of translating the text you may give the text some attributes like x and y. Instead of scaling the text you may change the font-size.

For the path you may choose svg transforms like this:

body {
  width: 200px;
}
.bg {
  fill: #beeb1b;
}
.cap {
  fill: #aaa8a9;
}
.trunk {
  fill: #231f20;
}
<svg xmlns="http://www.w3.org/2000/svg" tabindex="0" viewBox="0 0 351.33 722" aria-labelledby="bottletitle bottledesc" role="img">
    <title id="bottletitle">
        Bottle
    </title>
    <desc id="bottledesc">
        Bottle with battery indicator inside
    </desc>
    <g data-name="Layer 4" class="bg">
        <rect width="351.33" height="722" rx="23.33" ry="23.33"/>
    </g>
    <g data-name="Layer 3" class="cap">
        <rect x="146.81" y="60.9" width="57.71" height="73.67"/>
    </g>
    <g data-name="Layer 2" class="trunk">
        <path d="M173,153.25h57.75V223s1.08,25.33,30.41,56c27.06,28.29,35.34,60.33,35,71.33-.21,7,0,324.67,0,324.67s-3.33,7.33-9.33,7.33H117.12s-9-.33-9-6.66v-325s-.33-33,30.34-67c0,0,34.33-32.67,34.33-60.67S173.33,153.63,173,153.25Z" transform="translate(-26.46 -18.67)"/>
    </g>
    <svg viewBox="0 0 24 24">
        <defs>
            <linearGradient id="lg" x1="0.5" y1="1" x2="0.5" y2="0">
                <stop offset="0%" stop-opacity="1" stop-color="#2ecc71"/>
                <stop offset="24.2%" stop-opacity="1" stop-color="#2ecc71"/>
                <stop offset="24.2%" stop-opacity="0" stop-color="#2ecc71"/>
                <stop offset="100%" stop-opacity="0" stop-color="#2ecc71"/>
                <animate attributeName="y2" from="1" to="0" dur="500ms" repeatCount="2s" fill="freeze"/>
            </linearGradient>
        </defs>
        <path fill="url(#lg)" d="M15.67 4H14V2h-4v2H8.33C7.6 4 7 4.6 7 5.33v15.33C7 21.4 7.6 22 8.33 22h7.33c.74 0 1.34-.6 1.34-1.33V5.33C17 4.6 16.4 4 15.67 4z" stroke="#fff" transform="scale(.5,.5) rotate(90,12 12) translate(45,-12)"/>
        <text text-anchor="middle" dominant-baseline="middle" style="font:700 2.5px sans-serif;fill:#deba78" x="12" y="23">
            24.2%
        </text>
    </svg>
</svg>

Upvotes: 2

Related Questions