SVG fill property - svg

i have SVG the property(fill/stroke/stroke-width) should be in style="..." or else out side
example :
<rect x="10" y="10" fill="red" stroke="green" stroke-width="1" width="80px" height="50"/>
-----------------------OR--------------------
<rect x="10" y="10" style="fill:red; stroke:green; stroke-width:1;" width="80px" height="50"/>
Which one is correct? Both are working and reason....

As a matter of fact, both are correct. SVG was created in the late 90s. There all kinds of ideas how to auto-generate stuff were floating around. One was, for example, XSL-FO, which uses most of CSS's properties, but as attributes on elements:
<fo:block font-size="16px" color="red>Hello</fo:block>
In that time it seemed a good idea to double the possibilities to style SVG.
You need to take care, however, how the different properties cascade:
If an element has a style attribute, this is used first
If the SVG file has central CSS declarations, e.g., in a <style> element, those are used second.
The attribute is only used then, as fallback.
For illustration:
<svg xmlns="http://www.w3.org/2000/svg">
<style>rect { fill: yellow; }</style>
<rect fill="red" style="fill: green" width="100" height="100"/>
</svg>
The resulting color of the <rect> is... green.

Related

Is there a way for SVG strokes to "skip" intersecting each other, the same sort of way that CSS has `text-decoration-skip-ink`?

I could probably manually fake it using a solid-edged drop shadow filter around the strokes, set to the background color, but that's neither resilient nor ideal.
Visually, instead of this:
I want to have this (if the circle is on top):
A posible solution would be creating a mask with a white rectangle and a black stroked <use> element that is using the circle.
Please note that the white rectangle is covering all the svg element and the stroke-width of the <use> element is wider than the stroke of the circle.
This way you create a hole in the rect that is letting you to see whatever you have in the background.
<svg fill="none" stroke="black" stroke-width="3">
<mask id="m">
<rect width="100%" height="100%" fill="white" />
<use xlink:href="#c" stroke-width="10" />
</mask>
<rect x="10" y="5" width="70" height="70" mask="url(#m)" />
<circle id="c" cx="80" cy="75" r="40" />
</svg>

SVG or HTML text that scales to fully fit a container so it stretches, bot vertically and horizontally, disregarding aspect ratio

I need to make text automatically stretch in both dimensions, to fill a container. It will distort.
This shows the the container space in red
This shows what a long name would normally resize to put in that space and maintaining aspect ratio
.
This shows what my client wants to happen
.
I would prefer to use SVG but I will work with what works.
I have searched for a solution to the best of my abilities but all seem to either refer to maintaining aspect ratio or stretching text when the page or viewbox changes dimensions.
That's quite a broad question, but yes you can do it with svg, I'll let you implement it though since you didn't provided anything to chew on.
The key point is to set your svg's preserveAspectRatio to "none":
svg{
height: 100vh;
width: 50vw;
}
body{
margin:0;
}
<div>
<svg xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 300 40" preserveAspectRatio="none">
<text x="0" y="35" font-family="Verdana" font-size="35">
Hello, out there
</text>
</svg>
</div>
If your text is already part of an SVG (as it appears in your example), you will probably need to use a nested <svg> element.
<svg width="400" height="400">
<rect width="400" height="400" fill="rebeccapurple"/>
<!-- rect representing area that our text has to squeeze into -->
<rect x="20" y="50" width="200" height="50" fill="white"/>
<!-- x y width height match above rect -->
<!-- viewBox values need to match text bounds -->
<svg x="20" y="50" width="200" height="50"
viewBox="0 8 244 28" preserveAspectRatio="none">
<text x="0" y="35" font-family="Verdana" font-size="35">
HELLO THERE
</text>
</svg>
</svg>
The hardest part is workoing out the correct values for viewBox. It needs to match the bounds of the (normal unsqueezed) text.

Multiple preserveAspectRatio in svg?

I'm looking to have an svg fill a particular space in my layout, so preserveAspectRatio="none" seems like a good first approach.
However, within the svg, there is a mask that I do not want to stretch / warp. Rather, it should occupy 100% the width, with the height scaling according to its ratio. The two images illustrate the mask's behaviour when the parent svg is in either landscape or portrait. (Note: the grey in the image is the rest of the <svg>, which should stretch to fit)
Can the mask have its own aspectRatio settings? Is there a better way to achieve this? Or, is it even possible?
```
<!-- this should scale according to its bounding parent -->
<svg class="fix" viewbox="0 0 2880 1620" preserveAspectRatio="none..?">
<!-- this should scale according to some intrinsic ratio -->
<mask id="mask"
maskUnits="userSpaceOnUse"
maskContentUnits="userSpaceOnUse">
<rect fill="white" x="0" y="0" width="2880" height="1620" />
<path fill="black" d="M57.59,60h409c344.17,.... ...."/>
</mask>
<rect mask="url(#mask)" x="0" y="0" width="100%" height="100%" />
</svg>
```
edit: using mask-image instead of just mask seems possible (as it has additional positioning options), but this does not seem to work with svg elements.
You don't need to use preserveAspectRatio="none" to have the rectangle and mask fill the page. Just extend the <rect> and <mask> past the boundaries of the SVG in all directions. Root <svg> elements have overflow: visible by default, so the extended rect will fill SVGs parent container - as long as you extend far enough of course.
<rect mask="url(#mask)" x="-1000%" y="-1000%" width="3000%" height="3000%" />
I've used 1000% here, but you can adjust that if you need more or less (than 10x).
And note that we are just using the standard default SVG preserveAspectRatio. So we still get the automatic centerinng and scaling of the SVG.
body {
margin: 0;
padding: 0;
}
svg {
width: 100vw;
height: 100vh;
}
<svg viewbox="0 0 2880 1620">
<!-- this should scale according to some intrinsic ratio -->
<mask id="mask"
maskUnits="userSpaceOnUse"
maskContentUnits="userSpaceOnUse"
x="-1000%" y="-1000%" width="3000%" height="3000%">
<rect fill="white" x="-1000%" y="-1000%" width="3000%" height="3000%" />
<circle cx="1440" cy="810" r="400" fill="black"/>
</mask>
<rect mask="url(#mask)" x="-1000%" y="-1000%" width="3000%" height="3000%" />
</svg>
Demo in fiddle format

How to make SVG scale only on X axis?

I have the following SVG graphic that is currently scaling when the window is resized, but the aspect ratio is maintained. How could I get this to only scale on the X axis, and keep the Y at 80px?
<svg width="100%" viewBox="0 0 300 80">
<rect x="0" y="0" fill="yellow" height="80" width="100"/>
<rect x="100" y="0" fill="blue" height="80" width="100"/>
<rect x="200" y="0" fill="red" height="80" width="100"/>
</svg>
Thank you,
You have a couple of options. First, you could simply specify the height of the graphic, e.g. using CSS.
svg {
height: 80px;
width: 100%;
}
If that's not the effect you want, you can get more sophisticated with the preserveAspectRatio attribute. It's hard to say what value would work for you since it's not completely clear what you want (assuming the CSS approach above doesn't do it), but maybe something like:
<svg viewBox="0 0 300 80" preserveAspectRatio="none">
Check out the reference link for more details.

How I can get text with desired height and width?

I need to get text with desired height and width.
I tried to find something in documentation of svg but found only font-size and also I tried to use scale in such manner:
<text xmlns="http://www.w3.org/2000/svg" id="10996080909940" name="-1"
x="1782.9351809218" y="-751.796133712862" width="1" height="1" style="font:Arial;text-
anchor:start;stroke:#000000" transform="rotate(0) scale(2 2)"> SOME TEXT </text>
But I get too big size of text and in place not where I need.
If you mean you want the text to exactly fill an arbitrary width and height, then there isn't really an easy way to do it in SVG. You can't specifiy a width and height on the <text> element. At least not in the current SVG spec (1.1).
However there are several ways to achieve this effect with a bit of trickery.
One way is by using a transform, as you suggested:
<svg>
<text font-size="10px" font-family="Verdana" transform="translate(99,400) scale(3.5,13.7)">SQUASHED TEXT</text>
<rect x="100" y="300" width="300" height="100" fill="none" stroke="red" />
</svg>
A second way is by using an inner <svg> element and setting the viewBox to match the bounds of the text. You then set preserveAspectRatio="none".
<svg>
<svg x="100" y="100" width="300" height="100" viewBox="0.2 -7.3 86 7.3" preserveAspectRatio="none" overflow="visible">
<text font-size="10px" font-family="Verdana">SQUASHED TEXT</text>
</svg>
<rect x="100" y="100" width="300" height="100" fill="none" stroke="red" />
</svg>
This way is more verbose, but it has the advantage that once you have found the correct viewBox for a piece of text, you can make it fit any sized rectangle very easily. Just set the x,y,width and height of the inner <svg> to the size of the rectangle.
Demo here: http://jsfiddle.net/ZRgEF/3/

Resources