Putting SVG elements next to each other - html

I have a <text> and a <rect> element nested in a svg element. I want the <rect> element to begin right after the <text> ends. But it looks like I have to position them using x and y.
Is there any way to put them next to each other like regular HTML elements ?
<svg>
<text>1200</text>
<rect width='120' height='12'></rect>
</svg>

I only seem to be able to get it with this:
<svg height="30" width="100">
<text x="0" y="15" fill="red">SVG TEXT!</text>
</svg>
<svg height="30" width="100">
<rect width='120' height='12'></rect>
</svg>
See the Pen 'SVG Text and Box Test' by James Almeida here: http://codepen.io/jimmyplaysdrums/pen/ZYdEyw/

Related

What am I allowed to put in a textPath tag so that it follows the curve?

I've copied the second to last HTML snippet form here below and edited it by adding <p>uffa</p> in the text. As you can see, uffa is show at the bottom of the page instead of on the curve. Why is that? What am I allowed to put in the textPath tag so that it follows the curve?
<svg viewBox="0 0 500 500">
<path id="curve" d="M73.2,148.6c4-6.1,65.5-96.8,178.6-95.6c111.3,1.2,170.8,90.3,175.1,97" />
<text width="500">
<textPath xlink:href="#curve">
Dangerous Curves Ahead <p>uffa</p>
</textPath>
</text>
</svg>
Adding CSS tag in case there's a CSS trick to do that.
p is not an SVG element and therefore it is placed outside the SVG viewbox. Alternatively you can make use of tspan which is used to define a subtext within <text>
<svg viewBox="0 0 500 500">
<path id="curve" d="M73.2,148.6c4-6.1,65.5-96.8,178.6-95.6c111.3,1.2,170.8,90.3,175.1,97" />
<text width="500">
<textPath xlink:href="#curve">
Dangerous Curves Ahead <tspan>uffa</tspan>
</textPath>
</text>
</svg>

SVG text; align tspans to the left having text parent aligned to the right

Good day. Knowing x and y, I need to align the right edge of the multiline <text> to it. Problem is that content of the <tspan>s inside it should be aligned to the left. X and Y coordinates (with some offsets) serve as the starting coordinate for an <line>.
Smth like this:
Is there a possibility to achieve that behavior using svg's attributes and/or css?
I only came to what I can get the first <tspan>'s width via getBBox() and then use it as the line's start coordinate, by adding it to the x with text-align="start" on the parent <text>, but it's a runtime solution :(
Here's a simplified snippet:
<svg viewBox="0 0 500 500">
<!-- Knowing x and y to translate -->
<g transform="translate(200, 200)">
<text
x="0"
y="0"
fill="#000"
text-anchor="end"
dominant-baseline="hanging"
>
<tspan
font-size="20"
x="0"
>
Title
</tspan>
<tspan
font-size="15"
x="0"
dy="20"
>
Subtitle
</tspan>
<tspan
font-size="10"
x="0"
dy="15"
>
Description
</tspan>
</text>
</g>
<line
stroke="#f11"
stroke-width="3"
x1="205"
y1="210"
x2="305"
y2="210"
/>
</svg>
The answer is no.
SVG doen't have any native automatic layout facilities that will allow you to do what you want. It expects you to know where exactly you want to place each line of text.
You would need to use Javascript as you suggest.

Is it possible to apply partial text formatting to an svg string?

Is it possible to partially underline an svg text element?
The HTML tags allow for this in HTML, how do I achieve the same effect in an SVG text element?
If I write "We want <u>more</u> of this sort of thing", "more" is underlined.
Is there a way to do this with svg?
<text x="150" y="100">We want </text><text text-decoration="underline">more</text><text> of this sort of thing</text> gives me "We want " correctly displayed, but the other 2 text elements are located at x="0", y="0".
Presumably, If I want these to display as the same sentence, I need to calculate the position of the x and y coordinates and position them accordingly?
You can use the <tspan> within the <text> together with text-decoration="underline".
<svg width="500" height="500">
<text x="150" y="100">
We want <tspan text-decoration="underline">more</tspan> of this sort of thing</text>
</svg>
You're looking for <tspan> elements.
<svg width="500" height="500">
<text x="150" y="100">We want <tspan text-decoration="underline">more</tspan> of this sort of thing</text>
</svg>

SVG coordinates - mask & use & x/y attribute combined

I have a problem with SVG coordinates. I'm sure it's not a bug and it's probably explained somewhere in the documentation and therefore I don't question it. But for my needs I can't find other way to resolve the problem. Now to the point.
TL;DR
In SVG, this
<mask id="myMask" x="0" y="0">
...
</mask>
<use xlink:href="..." x="100" y="100" mask="#myMask">
changes the <use> x (or y) position together with the <mask> x (or y) position.
I want to keep the <mask> in its place.
Longer explanation
Background
In my web application I have a SVG path. I use it in multiple places so I decided to use the <use> element. Now, in some places I wanted to hide part of the path so I use <mask> element with a rectangle in it. There's also a situation where there is a stack of the same path placed one below another. To achieve this I used the y attribute for one of the <use> elements.
The question
Unfortunately, when I change the y coordinate of the <use> the <mask> attached to it also changes its y coordinate. The situation doesn't occur on <path> element nor other elements.
Below is an example (for simplicity I used <rect> elements).
Run the snippet to see four squares placed next to each other (two red and two yellow). The grey overlay represents the mask's boundaries. Squares will rather look like rectangles because they're cut in the half of their height by the <mask>. As you can see in the code, red squares are imported by <use> element and yellow ones are placed directly with <rect> element. Also the second and the fourth square are both moved 500 units downwards. My problem is clearly represented by the second square. It should be cut exactly like the fourth square but I need to do it the <use> way.
<svg xmlns="http://www.w3.org/2000/svg" width="200px" height="100px" viewBox="0 0 4000 1000">
<defs>
<rect id="svgRect" width="1000" height="1000"></rect>
<mask id="svgIconMask10">
<rect x="0" y="0" width="4000" fill="#ffffff" height="500"></rect>
</mask>
</defs>
<!-- Rectangle 1 -->
<use xlink:href="#svgRect" y="0" fill="#E5584C" mask="url(#svgIconMask10)"></use>
<!-- Rectangle 2 -->
<use xlink:href="#svgRect" x="1000" y="300" fill="#E5584C" style="mask: url(#svgIconMask10);"></use>
<!-- Rectangle 3 -->
<rect x="2000" y="0" width="1000" height="1000" fill="#E5D24C" style="mask: url(#svgIconMask10);"></rect>
<!-- Rectangle 4 -->
<rect x="3000" y="300" width="1000" height="1000" fill="#E5D24C" style="mask: url(#svgIconMask10);"></rect>
<!-- Mask area boundaries -->
<rect fill="transparent" stroke="#000" stroke-width="6px" x="0" y="0" width="4000" height="500" />
</svg>
You can apply the mask to a <g /> element and have the <use /> positioned independently:
<g style="mask: url(#svgIconMask10);">
<use xlink:href="#svgRect" x="1000" y="300" fill="#E5584C"></use>
</g>
http://jsfiddle.net/yb1q8dwh/

The applying order of SVG transforms

In W3C's spec, it says:
The value of the ‘transform’ attribute is a <transform-list>, which is defined as a list of transform definitions, which are applied in the order provided.
...
If a list of transforms is provided, then the net effect is as if each transform had been specified separately in the order provided
When I tried out the follow markups in firefox, chrome and IE10, all three rendered by doing translate first, then following by rotate! See the codepen snippet. What have I missed here? Or the implementations from the 3 browsers are not W3C compliant?
<svg width="180" height="200"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- This is the element before translation and rotation are applied -->
<rect x="0" y="0" height="100" width="100" style="stroke:#000; fill: #0086B2" fill-opacity=0.2 stroke-opacity=0.2></rect>
<!-- Now we add a text element and apply rotate and translate to both -->
<rect x="0" y="0" height="100" width="100" style="stroke:#000; fill: #0086B2" transform="rotate(45 100 50) translate(50)"></rect>
</svg>
The specification is pretty clear about the order which is that the rightmost transform is applied first.
If a list of transforms is provided, then the net effect is as if each transform had been specified separately in the order provided.
I.e,
<g transform="translate(-10,-20) scale(2) rotate(45) translate(5,10)">
<!-- graphics elements go here -->
</g>
is functionally equivalent to:
<g transform="translate(-10,-20)">
<g transform="scale(2)">
<g transform="rotate(45)">
<g transform="translate(5,10)">
<!-- graphics elements go here -->
</g>
</g>
</g>
</g>
If you want to sequentially change these transformations
you have to try this one
<g transform="translate(-10,-20) onmouseover=changeTransform(evt)">
function changeTransfrom(evt)
{
var id=evt.target;
id.setAttribute('transform',scale(0.5));
id.setAttribute('transform',rotate(30));
id.setAttribute('transform',skewY(45));
id.setAttribute('transform',matrix(2,2));
}