How to make SVG black bar with centered text responsive? - svg

I'm trying to make an SVG element fit to the bottom of the page with "Loading..." text centered regardless of the container's width. This is my current code which isn't working as the message is always in a fixed position.
<svg id="svg-bottom" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs></defs>
<g id="bottom">
<rect height="40" width="100%" y="0" x="0" fill="#000000" fill-opacity="0.676460598" id="panel"></rect>
<text id="status" font-family="GothamRounded-Medium, Gotham Rounded" font-size="20" font-weight="400" fill="#FFFFFF">
<tspan x="190.97" y="16">Loading…</tspan>
</text>
</g>

I solved the above with the following:
<text font-family="GothamRounded-Medium, Gotham Rounded" font-size="20" font-weight="400" fill="#FFFFFF" x="50%" y="50%" alignment-baseline="middle" text-anchor="middle">Loading…</text>

Related

What is the relationship between font-size and x/y percentages for positioning text elements in an SVG?

I am trying to center text in an area based on some shapes.
In the example below, each square has a height and width of 50% of the SVG. I am trying to center the very large "X" character. Intuitively, I thought setting the text's x and y to the center of any square (25%,25% or 25%,75% or 75%,75% or 75%,25%), but it is off. I need to adjust the percentage a little more to center them.
In the example below, it looks like my intuition is wrong in the upper left square, whereas adjusting the y% a little centers it in the upper right square. The smaller blue and green squares are included to show exactly where 25%,25% and 25%,75% are.
I notice that this changes when font size changes as well. Is there a way to center text based on the font size using percentages? What key concept am I missing for understanding why this doesnt work?
<svg preserveAspectRatio="xMinYMin meet" viewBox="0 0 200 200">
<style>
.f{font-family:monospace;font-size:80pt}
</style>
<rect width="50%" height="50%" y="0%" fill="red"/>
<rect width="50%" height="50%" y="50%" fill="green"/>
<rect width="50%" height="50%" y="0%" x="50%" fill="yellow"/>
<rect width="50%" height="50%" y="50%" x="50%" fill="blue"/>
<text x="25%" y="25%" class="f" dominant-baseline="middle" text-anchor="middle">X</text>
<text x="75%" y="29%" class="f" dominant-baseline="middle" text-anchor="middle" fill="blue">X</text>
<rect width="25%" height="25%" y="25%" x="25%" fill="blue"/>
<rect width="25%" height="25%" y="25%" x="75%" fill="green"/>
</svg>
Looks like you want dominant-baseline="central" rather than middle.
<svg preserveAspectRatio="xMinYMin meet" viewBox="0 0 200 200">
<style>
.f{font-family:monospace;font-size:80pt}
</style>
<rect width="50%" height="50%" y="0%" fill="red"/>
<rect width="50%" height="50%" y="50%" fill="green"/>
<rect width="50%" height="50%" y="0%" x="50%" fill="yellow"/>
<rect width="50%" height="50%" y="50%" x="50%" fill="blue"/>
<text x="25%" y="25%" class="f" dominant-baseline="central" text-anchor="middle">X</text>
<text x="75%" y="29%" class="f" dominant-baseline="central" text-anchor="middle" fill="blue">X</text>
<rect width="25%" height="25%" y="25%" x="25%" fill="blue"/>
<rect width="25%" height="25%" y="25%" x="75%" fill="green"/>
</svg>
The font allows for all characters to be displayed.
You need to change the baseline
https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/alignment-baseline
https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/dominant-baseline
https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/baseline-shift

Add inline labels to a horizontal bar with pure SVG

I use the bellow SVG code to build a horizontal bar chart. It is OK, but I need also two inline labels before and after the chart. I know how to add them with HTML and CSS, but I want to solve this only with pure SVG. How to do this?
<svg class="chart" width="300px" height="40">
<g transform="translate(0,0)">
<rect width="82%" height="22" fill="lightskyblue"></rect>
<rect width="100%" height="22" style="fill:none; stroke-width:1; stroke:gray;"></rect>
<text y="30" dx="0.25em" dy=".35em">0</text>
<text x="20%" y="10" dy=".35em" fill="red">|</text>
<text x="20%" y="30" dx="-0.25em" dy=".35em" fill="red">13</text>
<text x="100%" y="30" dx="-1.25em" dy=".35em">63</text>
</g>
</svg>
This is what I have now:
And this is what I want:
In order to make it work I'm using your code as a nested svg inside a larger svg element. Please observe I'm using a viewBox attribute where the x component has a negative value (-50) making space for the text.
svg{border:solid;}
<svg class="chart" width="300px" viewBox="-50 0 400 40">
<text y="20" x="-45">TXT</text>
<text x="345" y="20" text-anchor="end">TXT</text>
<svg viewBox="0 0 300 40" width="300">
<rect width="82%" height="22" fill="lightskyblue"></rect>
<rect width="100%" height="22" style="fill:none; stroke-width:1; stroke:gray;"></rect>
<text y="30" dx="0.25em" dy=".35em">0</text>
<text x="20%" y="10" dy=".35em" fill="red">|</text>
<text x="20%" y="30" dx="-0.25em" dy=".35em" fill="red">13</text>
<text x="100%" y="30" dx="-1.25em" dy=".35em">63</text>
</svg>
</svg>
I must tell you that I wouldn't percentages for the position and size of the rects. I would have done it using user units (without unit identifier) and I wouldn't have needed to wrap it in another svg element.
UPDATE
the OP is commenting
Can you give another example, without percentages for the position and size of the rects and without wrapping it in another svg element
svg{border:solid}
<svg class="chart" width="300px" viewBox="-50 0 400 40">
<text y="20" x="-45">TXT</text>
<text x="345" y="20" text-anchor="end">TXT</text>
<rect width="246" height="22" fill="lightskyblue"></rect>
<rect width="300" height="22" style="fill:none; stroke-width:1; stroke:gray;"></rect>
<text y="30" dx="0.25em" dy=".35em">0</text>
<text x="60" y="10" dy=".35em" fill="red">|</text>
<text x="60" y="30" dx="-0.25em" dy=".35em" fill="red">13</text>
<text x="300" y="30" dx="-1.25em" dy=".35em">63</text>
<svg>

Center Text on Rectangle in SVG

I am trying to center some text ("Go") onto a blue rectangle in an SVG image, however the text is only appearing at the top left corner.
<svg width="400" height="400" xmlns="http://www.w3.org/2000/svg">
<g>
<rect fill="#8080ff" height="400" width="400" y="0" x="0"/>
<text font-weight="bold" stroke="black" dominant-baseline="middle" text-anchor="middle" font-family="Arial, sans-serif" font-size="24" stroke-width="0" fill="#000000">Go</text>
</g>
</svg>
I think you are missing x="50%" y="50%" then it will work.
<svg width="400" height="400" xmlns="http://www.w3.org/2000/svg">
<g>
<rect fill="#8080ff" height="400" width="400" y="0" x="0"/>
<text font-weight="bold" stroke="black" x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" font-family="Arial, sans-serif" font-size="24" stroke-width="0" fill="#000000">Go</text>
</g>
</svg>

Cut off half of the SVG's text element

How can I make this
to look like this
So I want to halve the text element. I don't want to hide half of the text outside of SVG. Hiding it outside of g would be ok, but haven't found solution.
<svg width="500" height="500">
<g transform="translate(50,50)">
<rect width="80" height="50" style="fill:rgb(0,0,255);"/>
<text font-size="40" x="0" y="15" fill="black">SVG</text>
</g>
</svg>
JSFIDDLE:
http://jsfiddle.net/64nkLcdy/
Use the clip-path property :
<svg width="500" height="500">
<defs>
<clipPath id="myClip">
<rect width="80" height="50" />
</clipPath>
</defs>
<g transform="translate(50,50)">
<rect width="80" height="50" style="fill:rgb(0,0,255);" />
<text font-size="40" x="0" y="15" fill="black" clip-path="url(#myClip)">SVG</text>
</g>
</svg>
Use an <svg> element rather than a <g> as the svg element will clip its contents by default. The overflow property controls clipping i.e overflow="visible" doesn't clip but overflow="hidden" does.
<svg width="500" height="500">
<svg transform="translate(50,50)" width="80" height="50" overflow="hidden">
<rect width="80" height="50" style="fill:rgb(0,0,255);"/>
<text font-size="40" x="0" y="15" fill="black">SVG</text>
</svg>
</svg>

Responsively center SVG element inside another SVG element?

I'm trying to do something very simple in SVG:
Divide the entire viewport into two rectangles
Each rectangle should have a width 50% of the viewport's width
Each rectangle should have a height 100% of the viewport's height
In the center of each rectangle, draw another rectangle 100px wide and 40px high
The center of each of these "child" rectangles, for lack of a better term, should be aligned with the center of their respective "parent" rectangles--at any viewport size.
Here's an example of what I'd like to achieve, but using <text> elements instead of <rect> elements:
<svg version="1.1" width="100%" height="100%">
<svg x="0" y="0" width="50%" height="100%" overflow="visible">
<rect x="0" y="0" width="100%" height="100%" fill="#363636"></rect>
<text x="50%" y="50%" text-anchor="middle" text-color="#393939">Sign In</text>
</svg>
<svg x="50%" y="0" width="50%" height="100%" overflow="visible">
<rect x="0" y="0" width="100%" height="100%" fill="#999999"></rect>
<text x="50%" y="50%" text-anchor="middle">Sign Up</text>
</svg>
</svg>
How can I do this with rectangles--or any SVG shape, for that matter?
It turns out the secret to responsive SVG design is to have each object on the screen be its own <svg> element. In other words, use <svg> as a group tag.
Why? Because <svg> elements can be positioned using percentages.
To position the <svg> by its center rather than its upper, left-hand corner, use its transform="translate(dx,dy)" property.
In the case of our example, putting the text and "child" rectangles inside their own <svg> parent, and then transforming that, pulls off the desired effect:
<svg version="1.1" width="100%" height="100%">
<!-- Left Column -->
<svg x="0" y="0" width="50%" height="100%" overflow="visible">
<!-- "Parent" Rectangle -->
<rect x="0" y="0" width="100%" height="100%" fill="#363636"></rect>
<!-- "Child" Rectangle with Text -->
<svg x="50%" y="50%" width="116" height="40" overflow="visible">
<rect x="0" y="0" width="100%" height="100%" rx="20" ry="20" fill="#FFFFFF" transform="translate(-58, -25)"></rect>
<text x="0" y="0" text-color="#393939" transform="translate(-29, 0)">Sign Up</text>
</svg>
</svg>
<!-- Right Column -->
<svg x="50%" y="0" width="50%" height="100%" overflow="visible">
<!-- "Parent" Rectangle -->
<rect x="0" y="0" width="100%" height="100%" fill="#999999"></rect>
<!-- "Child" Rectangle with Text -->
<svg x="50%" y="50%" width="100" height="40" overflow="visible">
<rect x="0" y="0" width="100%" height="100%" rx="20" ry="20" fill="#FFFFFF" transform="translate(-50, -25)"></rect>
<text x="0" y="0" text-color="#393939" transform="translate(-25, 0)">Sign In</text>
</svg>
</svg>
</svg>
( Tested in Mac OS X Chrome 39.0 and iOS 8.1.2 Safari )

Resources