Is it possible to increase the width of a <rect> while keeping the height unchanged?
Use case:
There are different svg shapes that contain text like the one in the below example. Depending on the inputs this text may change. If the text is too long,
I want to increase the width to match the width of the text.
<svg viewBox="0 0 300 100" width="300px" height="100px">
<rect x="0" y="0" width="300" height="100" stroke="red" stroke-width="3px" fill="white"/>
<text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle">Hello World</text>
</svg>
In the above example, the visible size of the <rect> is 300x100 pixels.
If I want to keep the visible height and increase the width,
I found that I can increase the width value of all svg->width, svg->viewBox->width and rect->width attributes.
<svg viewBox="0 0 400 100" width="400px" height="100px">
<rect x="0" y="0" width="400" height="100" stroke="red" stroke-width="3px" fill="white"/>
<text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle">Hello World</text>
</svg>
Could this go wrong? Is there a better way?
SVGs are amazing when it comes to filling the box that you give it. Simply create a div container with the required width and height styles and then put the svg inside of it set at 100% width and height. and do the same with each graphic element.
Keep in mind that using this method means you will more than likly need to adjust the padding of the div to place the svg where you need it.
<div style="width:600px; height:150px;">
<svg width="100%" height="100%">
<rect x="0" y="0" width="100%" height="100%" stroke="red" stroke-width="3px" fill="white"/>
<text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle">Hello World</text>
</svg>
</div>
<br/>
<div style="width:100px; height:25px;">
<svg width="100%" height="100%">
<rect x="0" y="0" width="100%" height="100%" stroke="red" stroke-width="3px" fill="white"/>
<text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle">Hello World</text>
</svg>
</div>
Related
Please check my code link
<div class="suj_content">
<header class="suj_content_hd">
<div id="suj_content_hd_ytb"><iframe class="suj_content_hd_ytb" src="https://www.youtube.com/embed/kOc6ME2J_Us?mute=1&loop=1&playlist=kOc6ME2J_Us&autoplay=1&showinfo=0&controls=0" width="100%" height="100%" frameborder="0"></iframe></div>
<h2>
<svg id="suj_content_svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100% 100%" preserveAspectRatio="xMidYMid slice">
<defs>
<mask id="mask" x="0" y="0" width="100%" height="100%">
<rect x="0" y="0" width="100%" height="100%"></rect>
<text>
<tspan x="0" dy="33.333333333333%" alignment-baseline="middle" text-anchor="start">mittel</tspan><tspan x="0" dy="23.222222222222%" alignment-baseline="middle" text-anchor="start">stand</tspan><tspan x="0" dy="23.222222222222%" alignment-baseline="middle" text-anchor="start">digital</tspan> </text>
</mask>
</defs>
<rect x="0" y="0" width="100%" height="100%"></rect>
</svg>
</h2>
</header>
How can I set the width and height of SVG tag to fit its content (the tspan tags). The number of tspan tags is not fixed.
Thanks
First: you are using an invalid viewBox attribute. No percentages are allowed. The value of the viewBox is fromX fromY width height.
I am using a viewBox where the width is 41 - the width of the bounding box of the text.
Second: I suspect you intend to cut the text from the last rect. In this case you need the text to be white.
console.log(t.getBBox())
text{font-size:16px;}
<svg id="suj_content_svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 41 50" preserveAspectRatio="xMidYMid slice">
<defs>
<mask id="mask" x="0" y="0" width="100%" height="100%">
<rect x="0" y="0" width="100%" height="100%"></rect>
<text fill="white" id="t">
<tspan x="0" dy="25%" dominant-baseline="middle" text-anchor="start">mittel</tspan>
<tspan x="0" dy="25%" dominant-baseline="middle" text-anchor="start">stand</tspan>
<tspan x="0" dy="25%" dominant-baseline="middle" text-anchor="start">digital</tspan>
</text>
</mask>
</defs>
<rect x="0" y="0" width="100%" height="100%" mask="url(#mask)"></rect>
</svg>
Maybe somebody knows this case when text doesn't center vertically inside svg block
<pre>
<svg class="mask-text category-title" viewBox="0 0 69.34375 18"><defs><mask id="mask" x="0" y="0" width="100%" height="100%"><text class="svg-text" dominant-baseline="central" text-anchor="middle" x="50%" y="50%" font-family="Sans-serif" font-weight="900" fill="white">Colour</text></mask></defs><text class="svg-text" dominant-baseline="central" text-anchor="middle" x="50%" y="50%" font-family="Sans-serif" font-weight="900" fill="white">Colour</text>
<image class="svg-img" width="100%" height="100%" mask="url(#mask)" xlink:href="/uploads/vendor_groups/images/viz1.jpeg?width=1024&height=643" preserveAspectRatio="xMidYMid slice"></image>
</svg>
</pre>
I tried alignment-baseline and <text y="50%" x="50%" but it doesn't work
In the header of the svg write width="100vw" height="100vh"
In this case, vertical centering will work for the text with x="50%" and alignment-baseline
<pre>
<svg class="mask-text category-title" width="100vw" height="100vh" viewBox="0 0 69.34375 18"><defs><mask id="mask" x="0" y="0" width="100%" height="100%"><text class="svg-text" dominant-baseline="central" text-anchor="middle" x="50%" y="50%" font-family="Sans-serif" font-weight="900" fill="white">Colour</text></mask></defs><text class="svg-text" dominant-baseline="central" text-anchor="middle" x="50%" y="50%" font-family="Sans-serif" font-weight="900" fill="white">Colour</text>
<image class="svg-img" width="100%" height="100%" mask="url(#mask)" xlink:href="/uploads/vendor_groups/images/viz1.jpeg?width=1024&height=643" preserveAspectRatio="xMidYMid slice"></image>
</svg>
</pre>
Now in the browser window there is a frame relative to which it can calculate the vertical midpoint for the text <text y="50%"
UPDATE
You probably wanted to use text as a mask to fill the text with a cropped image.
As it turned out, the format of your image does not load.
So I took another image with exactly the same size as your image with 1024 X 643
<image class="svg-img"
xlink:href="https://i.stack.imgur.com/mlqrC.jpg" width="1024" height="643" mask="url(#mask)">
</image>
Your program had an extra line of text; I commented it out.
The font size was not specified, I chose font-size="250px"
Below is code that is responsive and works in all modern browsers except Edge
<style>
.container {
width:100vw;
height:100vh;
}
</style>
<div class="container">
<svg class="mask-text category-title" viewBox="0 30 1024 643" preserveAspectRatio="xMidYMid meet" >
<defs>
<mask id="mask" x="0" y="0" width="100%" height="100%" >
<rect width="100%" height="100%" fill="black" />
<text class="svg-text" font-size="250px" dominant-baseline="central" text-anchor="middle" x="50%" y="50%" font-family="Sans-serif" font-weight="900" fill="white">Colour</text>
</mask>
</defs>
<!-- <text class="svg-text" dominant-baseline="central" font-size="200px" text-anchor="middle" x="50%" y="50%" font-family="Sans-serif" font-weight="900" fill="white">Colour</text> -->
<image class="svg-img"
xlink:href="https://i.stack.imgur.com/mlqrC.jpg" width="1024" height="643" mask="url(#mask)">
</image>
</svg>
</div>
Edge scales and centers the image in a very peculiar way
So I had to replace the percent x = "50%" and y = "50%" with fixed values
In this version of the code, the application remains responsive and works in all modern browsers including Edge
<style>
.container {
width:100vw;
height:100vh;
}
</style>
<div class="container">
<svg class="mask-text category-title" viewBox="0 30 1024 643" preserveAspectRatio="xMidYMi meet">
<defs>
<mask id="mask" x="0" y="0" width="100%" height="100%" >
<rect width="100%" height="100%" fill="black" />
<text class="svg-text" dominant-baseline="central" font-size="250px" text-anchor="middle" x="512px" y="300px" font-family="Sans-serif" font-weight="900" fill="white">Colour</text>
</mask>
</defs>
<!-- <text class="svg-text" dominant-baseline="central" font-size="250px" text-anchor="middle" x="50%" y="50%" font-family="Sans-serif" font-weight="900" fill="white">Colour</text> -->
<image class="svg-img"
xlink:href="https://i.stack.imgur.com/mlqrC.jpg" width="1024" height="643" mask="url(#mask)">
</image>
</svg>
</div>
The size of the entire text block can be changed by edited the width,height in the parent block - .container
I have a text that I want to adjust it to the size of svg container and position it in the middle (horizontally and vertically). I am looking for relative way, not absolute. So far I have tried putting the text inside svg and adjust it with viewBox attribute and also the transform: scale function.
Is there any standard way to do this?
UPDATE:
With the help of commentators I was able to put the text in the middle of the svg container. Thank you!
However, I am still unable to put multiline text in the middle. The second code snippet is the farthest I came to the solution.
Working code for one line text:
<svg width="890" height="500"overflow="hidden;">
<g>
<rect x="0" y="0" width="542" height="495" fill="#6fdd6f"></rect>
<svg x="0" y="0" width="542" height="495" viewBox="0 0 100 100">
<text alignment-baseline="middle" dominant-baseline="middle" text-anchor="middle" x="50%" y="50%">TXT</text>
</svg>
</g>
</svg>
Code with multiline that needs to be adjusted to center:
<svg width="890" height="500"overflow="hidden;">
<g>
<rect x="0" y="0" width="542" height="495" fill="#6fdd6f"></rect>
<svg x="0" y="0" width="542" height="495" viewBox="0 0 100 100">
<text alignment-baseline="middle" dominant-baseline="middle" text-anchor="middle" >
<tspan x="50%" y="50%">TXT</tspan>
<tspan dy="1em" x="50%" y="50%">more TXT</tspan>
<tspan dy="2em" x="50%" y="50%">end of TXT</tspan>
</text>
</svg>
</g>
</svg>
My svg looks very bad in Google Chrome and Firefox too, the Svg borders have poor quality:
Meanwhile, in Illustrator the svg looks awesome:
I have saved the .svg file with this configuration:
What is happened?
If your SVG has a lot of horizontal and/or vertical lines, you can improve its appearance by aligning the coordinates to the pixel grid. I'll give you an example:
Here are three SVG images made of rounded rectangles. (The source code for these images is pasted below.)
In (A), the rectangle coordinates aren't aligned to the pixel grid at all. As a result, some of the lines are clear and sharp while others are fuzzy and a bit darker.
In (B), the rectangle coordinates are snapped to integer values, giving them a uniform appearance. However, they all look fuzzy now, because the antialiasing spreads each line across a width of two pixels.
In (C), the coordinates are snapped to integer values and given an additional offset of 0.5 pixels in the x and y directions. You should be able to see a definite improvement here.
If you're working in Illustrator, try viewing your artwork at 100% in "Pixel Preview" mode.
I would also recommend not using stroke widths smaller than 1 pixel. If you want to simulate thinner lines, try reducing the opacity instead.
<svg width="200" height="150" viewBox="0 0 200 150">
<!-- (Original drawing) -->
<rect x="0" y="0" width="200" height="150" fill="#47f" stroke="none" />
<g fill="none" stroke="#fff" stroke-width="1.2">
<rect x="20.1" y="20.1" width="160" height="110" rx="50" ry="50"/>
<rect x="25.3071" y="25.3071" width="149.5857" height="99.5857" rx="44.7929" ry="44.7929"/>
<rect x="30.5143" y="30.5143" width="139.1714" height="89.1714" rx="39.5857" ry="39.5857"/>
<rect x="35.7215" y="35.7215" width="128.7571" height="78.7571" rx="34.3785" ry="34.3785"/>
<rect x="40.9286" y="40.9286" width="118.3428" height="68.3428" rx="29.1714" ry="29.1714"/>
</g>
<text x="100" y="80" text-anchor="middle" font-family="sans-serif" font-size="20" fill="#fff">(A)</text>
</svg>
<svg width="200" height="150" viewBox="0 0 200 150">
<!-- (Lines snapped to integer coordinates) -->
<rect x="0" y="0" width="200" height="150" fill="#47f" stroke="none" />
<g fill="none" stroke="#fff" stroke-width="1.2">
<rect x="20" y="20" width="160" height="110" rx="50" ry="50"/>
<rect x="25" y="25" width="150" height="100" rx="45" ry="45"/>
<rect x="30" y="30" width="140" height="90" rx="40" ry="40"/>
<rect x="35" y="35" width="130" height="80" rx="35" ry="35"/>
<rect x="40" y="40" width="120" height="70" rx="30" ry="30"/>
</g>
<text x="100" y="80" text-anchor="middle" font-family="sans-serif" font-size="20" fill="#fff">(B)</text>
</svg>
<svg width="200" height="150" viewBox="0 0 200 150">
<text x="100" y="80" text-anchor="middle" font-family="sans-serif" font-size="20" fill="#fff">(A)</text>
<!-- (Lines snapped to integer coordinates with 0.5px offset) -->
<rect x="0" y="0" width="200" height="150" fill="#47f" stroke="none" />
<g fill="none" stroke="#fff" stroke-width="1.2">
<rect x="20.5" y="20.5" width="160" height="110" rx="50" ry="50"/>
<rect x="25.5" y="25.5" width="150" height="100" rx="45" ry="45"/>
<rect x="30.5" y="30.5" width="140" height="90" rx="40" ry="40"/>
<rect x="35.5" y="35.5" width="130" height="80" rx="35" ry="35"/>
<rect x="40.5" y="40.5" width="120" height="70" rx="30" ry="30"/>
</g>
<text x="100" y="80" text-anchor="middle" font-family="sans-serif" font-size="20" fill="#fff">(C)</text>
</svg>
In your "bad" example, the SVG has been reduced to roughly half size. That means some of the lines that are approx 1 pixel thick in your "good" example are now only around 0.5 pixels thick. That doesn't give the anti-aliasing routines in the SVG renderer much to play with. Try making the stroke widths thicker.
You should get better results then.
This is the code i have so far but it's not good
<svg
width="200"
height="13">
<g
id="layer1">
<text
style="font-size:13px;font-family:Arial;"
x="0"
y="13"
id="">THIS IS A TEST</text>
</g>
</svg>
i am trying to get the text to fit perfectly in the box and etc. also need to add a background color to it.
This can serve:
<svg
baseProfile="full"
width="200"
height="13">
<g id="layer1">
<rect width="100%" height="100%" fill="red" />
<text
style="font-size:13px;font-family:Arial;"
x="0"
y="13"
id="">THIS IS A TEST</text>