I am using a SVG instead of an actual emoji in my website to make sure that it looks the same on all devices. However, the edges of the SVG are appearing blurry and pixelated when I view it on my iPhone. (does not happen on desktop.)
As you can see from the first image (✌️emoji svg), some parts of the SVG are blurry while others are crisp. In the second svg, (💭emoji) the edges are completely blurry.
It is not the svg that is causing the blurriness, it appears completely crisp on desktop.
This is how I am inserting the svg:
.emoji {
background-position:center center;
background-repeat:no-repeat;
background-size:1em 1em;
display:inline-block;
height:1em;
margin:0 .05em 0 .1em;
vertical-align:-0.1em;
width:1em
}
.emoji.victory-hand {
background-image: url(../emojis/emoji/victory_hand_color_default.svg);
}
.emoji.thought-balloon {
background-image: url(../emojis/emoji/thought_balloon_color.svg);
}
<h2>hello<i class="emoji victory-hand"></i></h2>
<h2>projects <i class="emoji thought-balloon"></i></h2>
The svg is fine when I use an svg viewer to view it or use a computer, it only appears blurry on mobile. Does anyone know why this is happening?
As commented, iOS safari apparently renders masked images at a fixed resolution.
So the image gets blurry when zooming in.
That's probably the reason, why some contours in the OP's emoji are crisp while others are blurry/pixelated.
Left: masked shape; right: clipped shape
body {
font-size: 5em;
background: #000;
}
svg {
height: 100%
}
.icon-wrap {
height: 1em;
display: inline-block;
}
<div class="icon-wrap">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
<defs>
<mask id="mask">
<rect x="0" y="0" width="100%" height="100%" fill="#000"></rect>
<path fill="#fff" d="M62.05 7.31c6.86 0 14.13 6.46 14.41 12.79c0.21 4.74-1.42 10.5-3 16.07c-1.98 6.98-3.68 13.01-2.02 17.42a3 3 0 0 0 2.81 1.94h0.11l7.2-0.25h0.06c7.33 0 13.3 5.96 13.31 13.3l0.05 42.21c0 2.5-0.97 4.86-2.74 6.63s-4.12 2.75-6.63 2.75h-0.08c-8.6-0.07-21.51-0.41-34.19-1.6c-8.6-0.81-17.48-2.09-24.11-5.85c-2.2-1.25-4.58-1.54-6.49-1.78c-0.76-0.09-1.47-0.18-2.03-0.32c-4.2-0.99-7.14-4.61-7.15-8.8l-0.08-32.75c-0.01-3.78 2.69-6.95 6.42-7.53c0.15-0.02 0.31-0.06 0.45-0.11c0.56-0.18 13.94-4.55 24.05-12.45c4.87-3.81 9.05-9.67 11.17-15.68s2.1-12.36 2.09-17.5c0-2.44-0.01-5.74 0.41-6.74a10.97 10.97 0 0 1 5.98-1.75"></path>
</mask>
</defs>
<radialGradient id="a" cx="51.77" cy="31.401" r="87.039" gradientTransform="matrix(-.00218 1 -.7873 -.00172 76.604 -20.315)" gradientUnits="userSpaceOnUse">
<stop offset=".6" stop-color="#FFCA28" />
<stop offset="1" stop-color="#FFB300" />
</radialGradient>
<path mask="url(#mask)" fill="url(#a)" d="M85.52 121.67c-8.63-.07-21.58-.41-34.32-1.61-8.77-.83-17.83-2.14-24.71-6.04-1.94-1.1-4.06-1.37-5.94-1.6-.8-.1-1.55-.19-2.19-.34-4.88-1.15-8.29-5.37-8.31-10.26l-.07-32.75c-.01-4.53 3.22-8.32 7.69-9.02.08-.01.15-.03.23-.05.55-.18 13.69-4.46 23.59-12.2 4.66-3.64 8.65-9.25 10.68-15 2.02-5.73 2.01-11.98 2-17 0-3.24-.01-7.27.87-7.86 2.14-1.41 4.5-2.13 7.01-2.13 7.72 0 15.6 7.05 15.91 14.23.22 4.98-1.45 10.86-3.06 16.54-1.9 6.73-3.55 12.54-2.06 16.49.22.59.78.97 1.4.97l7.29-.25h.07c8.16 0 14.8 6.64 14.81 14.79l.05 42.21c0 2.91-1.12 5.64-3.18 7.69a10.81 10.81 0 01-7.69 3.19h-.07z" />
</svg>
</div>
<div class="icon-wrap">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
<defs>
<clipPath id="clip">
<rect x="0" y="0" width="100%" height="100%" fill="#000"></rect>
<path fill="#fff" d="M62.05 7.31c6.86 0 14.13 6.46 14.41 12.79c0.21 4.74-1.42 10.5-3 16.07c-1.98 6.98-3.68 13.01-2.02 17.42a3 3 0 0 0 2.81 1.94h0.11l7.2-0.25h0.06c7.33 0 13.3 5.96 13.31 13.3l0.05 42.21c0 2.5-0.97 4.86-2.74 6.63s-4.12 2.75-6.63 2.75h-0.08c-8.6-0.07-21.51-0.41-34.19-1.6c-8.6-0.81-17.48-2.09-24.11-5.85c-2.2-1.25-4.58-1.54-6.49-1.78c-0.76-0.09-1.47-0.18-2.03-0.32c-4.2-0.99-7.14-4.61-7.15-8.8l-0.08-32.75c-0.01-3.78 2.69-6.95 6.42-7.53c0.15-0.02 0.31-0.06 0.45-0.11c0.56-0.18 13.94-4.55 24.05-12.45c4.87-3.81 9.05-9.67 11.17-15.68s2.1-12.36 2.09-17.5c0-2.44-0.01-5.74 0.41-6.74a10.97 10.97 0 0 1 5.98-1.75"></path>
</clipPath>
</defs>
<radialGradient id="a" cx="51.77" cy="31.401" r="87.039" gradientTransform="matrix(-.00218 1 -.7873 -.00172 76.604 -20.315)" gradientUnits="userSpaceOnUse">
<stop offset=".6" stop-color="#FFCA28" />
<stop offset="1" stop-color="#FFB300" />
</radialGradient>
<path clip-path="url(#clip)" fill="url(#a)" d="M85.52 121.67c-8.63-.07-21.58-.41-34.32-1.61-8.77-.83-17.83-2.14-24.71-6.04-1.94-1.1-4.06-1.37-5.94-1.6-.8-.1-1.55-.19-2.19-.34-4.88-1.15-8.29-5.37-8.31-10.26l-.07-32.75c-.01-4.53 3.22-8.32 7.69-9.02.08-.01.15-.03.23-.05.55-.18 13.69-4.46 23.59-12.2 4.66-3.64 8.65-9.25 10.68-15 2.02-5.73 2.01-11.98 2-17 0-3.24-.01-7.27.87-7.86 2.14-1.41 4.5-2.13 7.01-2.13 7.72 0 15.6 7.05 15.91 14.23.22 4.98-1.45 10.86-3.06 16.54-1.9 6.73-3.55 12.54-2.06 16.49.22.59.78.97 1.4.97l7.29-.25h.07c8.16 0 14.8 6.64 14.81 14.79l.05 42.21c0 2.91-1.12 5.64-3.18 7.69a10.81 10.81 0 01-7.69 3.19h-.07z" />
</svg>
</div>
Workarounds:
replace <mask> with <clipPath>
use compound paths for cutout shapes like holes (e.g. in the letter O)
try another emoji library with a more simplistic/cleaner svg structure
Safari has this really big issue where svgs are not rendered properly for its device's retina display.
Try adding:
-webkit-transform: translate3d(0,0,0)
To the svg.
If not, it might not be fixable as any svgs in Safari do not work well with outlines.
Also try adding:
shape-rendering="geometricPrecision"
To the svg.
Instead if that does not work either try:
shape-rendering = "crispEdges"
Instead of geometricPrecision, that disables anti-aliasing on the image through the browser.
Related
I'm trying to build a website where I need to overlap two images for the background (one is JPG and the other one is SVG file). But I am unable to overlay both of them as my SVG image has some extra white part in the start page. I want the part from where the gray starts to the bottom. But I am unable to do that.
Here is the SVG code and image : https://www.svgviewer.dev/s/CnqCU38Y
I've tried to do the following with my CSS code, but have failed to get the desired results.
.main-page {
width: 100%;
height: 100vh;
background-image: url('assets/Main-page/bg-cropped.svg'), url('assets/Main-page/1079171177-preview_PosterImage.png');
background-repeat: no-repeat;
}
Here are the images : https://imgur.com/a/oEkMeU3
Can anyone please help me out with this one?
May be transform="translate(0 0):
<svg viewBox="0 0 1920 1134.399" height="1134.399" width="1920" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient gradientUnits="objectBoundingBox" y2="0.664" x2="0.969" y1="0.176" id="linear-gradient">
<stop offset="0"></stop>
<stop stop-opacity="0" offset="1"></stop>
</linearGradient>
<clipPath id="clip-path">
<path fill="url(#linear-gradient)" d="M0,0H1920V769.66S1440.573,942.4,960.4,942.4,0,769.66,0,769.66Z" id="bg"></path>
</clipPath>
</defs>
<g transform="translate(0 0)" data-name="bg" id="bg-2">
<path fill="url(#linear-gradient)" transform="translate(0 0)" d="M0,0H1920V769.66S1440.573,942.4,960.4,942.4,0,769.66,0,769.66Z" data-name="bg" id="bg-3"></path>
</g>
</svg>
In Chromium it's not visible - but it is on pretty much everything else - but there is a what looks like a border around the SVG, well, you can see the top and bottom lines (top one is not clear here, but it's there).
This is the HTML that gets generated.
<div class="purple-gradient-background header-has-block">
<div class="container px-md-5 embed-block">[[omitted]]</div>
<!--?xml version="1.0" encoding="UTF-8"?-->
<svg viewBox="0 0 1440 86" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient x1="10.5864654%" y1="50%" x2="100%" y2="50%" id="linearGradient-1">
<stop stop-color="#F28F53" offset="0%"></stop>
<stop stop-color="#ED555F" offset="100%"></stop>
</linearGradient>
</defs>
<g id="svg_graphic-standalone-1-V4" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M0,50.0114382 C309.731575,4.65760206 558.064908,4.66285455 745,50.0271956 C931.935092,95.3915367 1163.60176,95.3862842 1440,50.0114382 L1440,86 L0,86 L0,50.0114382 Z" id="BG" fill="#FAF7FB"></path>
<path d="M1440,50.3528061 C1163.60176,95.6971472 931.935092,95.6871472 745,50.3228061 C558.064908,4.95846499 309.731575,4.96846499 0,50.3528061 L0,50.3528061 L0,34.3528061 C309.601759,-10.7852514 557.935092,-11.2785847 745,32.8728061 C932.064908,77.0241969 1163.73157,77.5175302 1440,34.3528061 Z M1440,-1.52766688e-12 L0,-1.52766688e-12 L0,-1.64719392 L1440,-1.64719392 L1440,-1.52766688e-12 Z" id="Combined-Shape" fill="url(#linearGradient-1)"></path>
</g>
</svg>
</div>
The enclosing <div> goes around other items as well so cannot be causing the line.
I have tried removing the stroke information from the g element, and setting the width to zero. It had no effect.
Examination of the CSS assigned to the SVG shows there is no border, margin or padding:
box-sizing: border-box
display: inline
float: none
line-height: 24px
position: static
z-index: auto
how can i show in internet explorer 11 the same shadow that I can apply in chrome using this rule?
filter: drop-shadow(6px 6px 7px rgba(0,0,0,0.5));
This is my working chrome markup HTML
<div class="cta-image-container">
<div>
<svg class="svg-cta-image">
<image filter="url(#dropshadow)" width="640" height="580" class="cta-image cta-image-1-3" xlink:href="https://anekitalia.com/wp-content/uploads/media/justfun-viaggi-evento-viaggia-split.jpg"></image>
</svg>
</div>
<div>
<svg class="svg-cta-image">
<image width="640" height="580" class="cta-image cta-image-2-3" xlink:href="https://anekitalia.com/wp-content/uploads/media/justfun-viaggi-evento-viaggia-split.jpg"></image>
</svg>
</div>
<div>
<svg class="svg-cta-image">
<image width="640" height="580" class="cta-image cta-image-3-3" xlink:href="https://anekitalia.com/wp-content/uploads/media/justfun-viaggi-evento-viaggia-split.jpg"></image>
</svg>
</div>
<svg>
<defs>
<clipPath id="split-1-3">
<polygon points="222,580 0,580 0.12,0 176,0"></polygon>
</clipPath>
</defs>
</svg>
<svg>
<defs>
<clipPath id="split-2-3">
<polygon points="400,0 196,0 242,580 446,580"></polygon>
</clipPath>
</defs>
</svg>
<svg>
<defs>
<clipPath id="split-3-3">
<polygon points="640,0 420,0 466,580 640,580"></polygon>
</clipPath>
</defs>
</svg>
and this is the CSS
.cta-image-container svg{
position: absolute;
}
.cta-image-container {
width: 640px;
height: 580px;
margin: 0 25px 0 25px;
filter: drop-shadow(6px 6px 7px rgba(0,0,0,0.5));
position: relative;
}
.cta-image {
max-width: 100%;
max-height: 100%;
position: absolute;
}
.svg-cta-image {
width: 640px;
height: 580px;
}
.cta-image-1-3 {
clip-path: url(#split-1-3);
}
.cta-image-2-3 {
clip-path: url(#split-2-3);
}
.cta-image-3-3 {
clip-path: url(#split-3-3);
}
Here you can find a chrome working CODEPEN
As rx2347 pointed out, IE does not support CSS Filter Effects
So the only way to add a drop shadow is apply the effect inside your svg by using a blurred black polygon positioned behind the image.
This is an updated version of your codepen with the applied effect https://codepen.io/samwalker/pen/XWbzpZX
I don’t have a PC/IE 11 so I used BrowserStack to test and the results below:
Notes:
1. I had to increase the size of the viewbox/svg so the shadow wasn’t clipped
<svg class="svg-cta-image" viewBox="0 0 660 600">
2. Created the feGaussianBlur as an svg filter def.
<filter id="blurFilter">
<feGaussianBlur stdDeviation="5" />
<filter />
The 'blur size' is set by the stdDeviation attr.
A good tool to show what is possible with IE filters is Hands on: SVG filter Effects it’s part of Azure websites & shows MS IE compatible filters
3. Created a group element inside the SVG the same shape as clip-path, this is our 'shadow'
<g id="shadow" fill="black" filter="url(#blurFilter)" fill-opacity="0.5">
<polygon points="222,580 10,580 10,10 176,10"></polygon>
<polygon points="400,10 196,10 242,580 446,580"></polygon>
<polygon points="640,10 420,10 466,580 640,580"></polygon>
</g>
The shadow’s style is set with fill colour and fill-opacity.
I had to offset the polygon’s start points by 10px to match the new position of the image.
4. Combined the 3 polygons into a single clipping path so you only need to load the image once. If you are going to use 3 different images you can easily change this back.
5. Offset the image from the edge of the svg box and reset it’s size x="10" y="10" width="640" height="580", you maybe want to do this in the css.
There are probably some changes you’ll want to make but hopefully this will get you on the right path.
Full markup below:
.cta-image-container {
width: 660px;
height: 600px;
margin: 25px auto;
position: relative;
}
<div class="cta-image-container">
<div>
<svg class="svg-cta-image" viewBox="0 0 660 600"><!-- increased veiwbox by 20px so shadow isn’t clipped -->
<defs xmlns="http://www.w3.org/2000/svg">
<clipPath id="split-in-3"><!-- combined clipping path -->
<polygon points="222,580 0,580 0.12,0 176,0"></polygon>
<polygon points="400,0 196,0 242,580 446,580"></polygon>
<polygon points="640,0 420,0 466,580 640,580"></polygon>
</clipPath>
<filter id="blurFilter">
<feGaussianBlur stdDeviation="5" /><!-- size of shadow -->
<filter />
</defs>
<g id="shadow" fill="black" filter="url(#blurFilter)" fill-opacity="0.5"><!-- `fill` & `fill-opacity` set the shadow’s color -->
<polygon points="222,580 10,580 10,10 176,10"></polygon><!--`0`s replaced by 10 to offset shadow from edge of svg -->
<polygon points="400,10 196,10 242,580 446,580"></polygon>
<polygon points="640,10 420,10 466,580 640,580"></polygon>
</g>
<image clip-path="url(#split-in-3)" x="10" y="10" width="640" height="580" class="cta-image cta-image-1-3" xlink:href="https://anekitalia.com/wp-content/uploads/media/justfun-viaggi-evento-viaggia-split.jpg"></image><!-- positioned at 10px `x` & `y` to offset from edge of svg --><!-- reset size to match original -->
</svg>
</div>
</div>
I have a situation where I have a SVG graphic whose width is a percentage of the viewport, and whose height is fixed. Inside the graphic I have an SVG image element which I want to always fill its immediate container without distorting, much as would be achieved by using CSS background-size: fill.
How can I achieve this using my SVG?
Here's a minimal setup of the problem (and a codepen):
<svg width=100% height=300>
<rect width=100% height=300 stroke="blue" stroke-width=30 fill="transparent" />
<image xlink:href="//unsplash.it/500/300" width=100% height=100% />
</svg>
In the above snippet, I need the image to fill the entire container without distorting (in this instance, the container being the root SVG), regardless of viewport width.
I can't switch to regular HTML because the graphic I'm working on has an SVG clipping mask applied to the image element.
I found this question, which seems close to what I'm asking, but I don't think answers my question:
How can I make my embedded svg image stetch to fill a container?
In hopes of avoiding the XY problem, here's the actual SVG graphic I'm working on. And the (fixed-height, variable-width) result I'm trying to achieve:
Svg scaling with image
If you add a viewbox to the svg the svg knows how to scale.
Now adding the same viewBox ratio as the svg makes it so the svg will always have the same scale as the image.
You can always scale the image to its inside the viewBox.
Then it will always scale with the svg.
svg {
border: 2px solid black;
}
<svg width="100%" height="100%" viewBox="0 0 500 300">
<image width="500" height="300" xlink:href="//unsplash.it/500/300"/>
</svg>
To keep the height of the image unchanged, set the fixed value of the viewport height and preserveAspectRatio = "none"
<svg width="100%" height="300" viewBox="0 0 500 300" preserveAspectRatio = "none">
<image width="500" height="300" xlink:href="//unsplash.it/500/300"/>
</svg>
UPD
The proportions of the picture will not change, the height remains fixed when using preserveAspectRatio="xMinYMin slice"
<svg width="100%" height="300" viewBox="0 0 500 300" preserveAspectRatio="xMinYMin slice">
<image width="100%" height="300" xlink:href="//unsplash.it/500/300" />
</svg>
UPD2
I looked your codepen Like the idea. I've finished it with your permission. Modified some parameters
<svg width="100%" height="400" preserveAspectRatio="xMinYMin slice">
<defs>
<mask id="clipping">
<rect width="100%" height="400" fill="white"/>
<ellipse cx="50%" cy="120%" rx="75%" ry="37%"/>
</mask>
<linearGradient id="Gradient1" x1="0" x2="0" y1="0" y2="1">
<stop offset="0%" stop-color="white"/>
<stop offset="100%" stop-color="blue"/>
</linearGradient>
</defs>
<rect width="100%" height="400" fill="orange" mask="url(#clipping)" transform="translate(-20 12) rotate(-2.5)" />
<image xlink:href="https://unsplash.it/1000/500" width="100%" height="400" mask="url(#clipping)" transform="translate(0 -10)" />
<rect width="100%" height="400" fill="url(#Gradient1)" mask="url(#clipping)" transform="translate(0 -10)" opacity="0.25" />
</svg>
I ended up using two SVGs and an image which used a clipping mask defined in the first SVG to clip it down. I was able to make the SVGs scale by only defining a viewbox, not a width and height. I opted to use a fixed aspect ratio instead of a fixed height, percentage width, as I had originally planned.
body > * {
position: absolute;
top: 0;
left: 0;
width: 100%;
}
img {
clip-path: url(#clipper);
}
<svg viewBox="0 0 1000 500">
<defs>
<symbol id="arch" viewBox="0 0 1000 400">
<path d="M0 0 H 1000 V 400 Q 500 300, 0 400" />
</symbol>
<clipPath id="clipper" clipPathUnits="objectBoundingBox">
<path d="M0 0 H 1 V 1 Q .5 .75, 0 1" />
</clipPath>
<linearGradient id="Gradient1" x1="0" x2="0" y1="0" y2="1">
<stop offset="0%" stop-color="#87AFBF"/>
<stop offset="100%" stop-color="#002855"/>
</linearGradient>
</defs>
<use href="#arch" width="100%" y="-40" fill="#F9B000" transform="translate(-20 12) rotate(-2.5)" />
</svg>
<img src="//unsplash.it/1000/400" alt="">
<svg viewBox="0 0 1000 500">
<use href="#arch" y="-50" fill="url(#Gradient1)" opacity="0.75" />
</svg>
CodePen
I have an SVG inlined to html code. Its is scaled to fit width with preserving aspect ratio. Is there a way to set font size fixed to viewport that can be controlled with media queries?
EDIT:
The problem is when i set fixed font-size within width range the font is resized anyway relative to svg size.
#svg-container {
width: 100%;
padding-bottom: 70%;
overflow: hidden;
border: 1px solid red;
}
#svg-container svg text tspan {
font-size: 14px;
}
#media (min-height: 800px) {
#svg-container svg text tspan {
font-size: 50px;
}
}
<div id="svg-container">
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
viewBox="0 0 500 350"
data-name="Layer 1"
id="Layer_1"
inkscape:version="0.91 r13725"
sodipodi:docname="Desktop_Enhanced.svg"
width="100%"
style="position: absolute; left: 0; top: 0;"
>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1280"
inkscape:window-height="961"
id="namedview51"
showgrid="false"
inkscape:zoom="1.0054235"
inkscape:cx="231.42799"
inkscape:cy="361.93137"
inkscape:window-x="1272"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="Layer_1"
fit-margin-bottom="150" />
<metadata
id="metadata75">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>Desktop</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs3">
<style
id="style5">.cls-1{fill:#da1f26;}.cls-2{fill:#252e43;}.cls-3{fill:#d1d3d4;}</style>
</defs>
<title
id="title7">Desktop</title>
<polyline
id="polyline9"
points="329.4 62.24 343.54 76.39 329.4 90.53"
class="cls-1"
style="fill:#da1f26"
transform="translate(59.579252,-43.513817)" />
<polyline
id="polyline11"
points="333.56 328.83 347.7 342.97 333.56 357.11"
class="cls-2"
style="fill:#252e43"
transform="translate(59.579252,-43.513817)" />
<path
id="path35"
d="m 394.84925,294.48618 -25,0 c -57.81,0 -77.28,-34.66 -96.1,-68.18 -15.35,-27.34 -29.86,-53.16 -63.9,-53.16 l -31.27,0 0,10 31.3,0 c 28.19,0 40.7,22.27 55.18,48.06 9.68,17.23 19.69,35.06 35.5,49.13 18.26,16.22 40.93,24.15 69.33,24.15 l 25,0 z"
class="cls-2"
inkscape:connector-curvature="0"
style="fill:#252e43" />
<path
id="path43"
d="m 390.97925,27.876183 -21.09,0 c -28.4,0 -51.07,7.9 -69.32,24.15 -15.81,14.08 -25.82,31.9 -35.5,49.129997 -14.48,25.79 -27,48.06 -55.18,48.06 l -31.31,0 0,10 31.3,0 c 34,0 48.54,-25.82 63.9,-53.16 18.8,-33.569997 38.3,-68.179997 96.11,-68.179997 l 21.09,0 z"
class="cls-1"
inkscape:connector-curvature="0"
style="fill:#da1f26" />
<path
id="path45"
d="m 429.38925,17.956183 a 14.92,14.92 0 1 0 14.92,14.92 14.92,14.92 0 0 0 -14.92,-14.92 z m 0,21 a 6.08,6.08 0 1 1 6.08,-6.08 6.08,6.08 0 0 1 -6.08,6.08 z"
class="cls-1"
inkscape:connector-curvature="0"
style="fill:#da1f26" />
<path
id="path47"
d="m 433.38925,284.53618 a 14.92,14.92 0 1 0 14.92,14.95 14.92,14.92 0 0 0 -14.92,-14.95 z m 0,21 a 6.08,6.08 0 1 1 6.09,-6.05 6.08,6.08 0 0 1 -6.09,6.05 z"
class="cls-2"
inkscape:connector-curvature="0"
style="fill:#252e43" />
<flowRoot
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="flowRoot4236"
xml:space="preserve"
transform="translate(0,-72.53)"><flowRegion
id="flowRegion4238"><rect
y="179.54243"
x="18.988897"
height="58.373276"
width="94.241196"
id="rect4240" /></flowRegion><flowPara
id="flowPara4242">ZakładaZ</flowPara></flowRoot> <text
x="27.791037"
y="169.90349"
font-size="20px"
id="text49-1"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:15px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Bold';text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#252e43;fill-opacity:1"
sodipodi:linespacing="125%">
<tspan
sodipodi:role="line"
id="tspan4528"
x="27.791037"
y="169.90349">PLEASE CHOOSE</tspan>
</text>
</svg>
</div>
The short answer is no.
If the text is in an SVG with a viewBox, and the SVG gets scaled, its contents get scaled also. There is no way to make the text have a "global" size that is unaffected by the SVG scaling.
The only possible solution would be calculate the scaling factor using Javascript and dynamically update the font size every time the SVG size changed.
I'd recommend nested SVG tags. You can keep your outermost SVG without viewBox and add all text under this tag, while adding a second SVG to cover the full area but using a viewBox.
You'll need to change positions for the text from absolute to relative values, but it works quite well.
That way your text will change position with the svg size but not scale the text. The inner SVG will, though, since you set a viewBox.
Example: JS for variable container, SVG always fills the div.
The scaling is pure SVG.
function changeCircleDiv(element) {
s = document.getElementById("container").style;
s.width = element.value + 'px';
s.height = s.width;
}
body {
font-size: 2em;
}
<input type="number" onchange="changeCircleDiv(this);" value="100"></input>
<div id="container" style="width: 100px; height: 100px;">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="100%" height="100%">
<svg width="100%" height="100%" viewBox="0 0 20 20">
<circle cx="10" cy="10" r="8" stroke="black" fill="none"/>
</svg>
<text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle">Center</svg>
</svg>
</div>
In the end...
I have removed text from svg and added div text block with absolute positioning inside shared html container. That worked prefect. Div's appearance is controlled over css with media queries - it is independent from svg scaling.
Your can see diagram in action at: https://www.xtech.pl/jak-to-dziala-dla-dostawcy (scroll down to second section on the page, then you can resize your screen to see how it works).
You can do it in this way "Responsive SVG with sticky text"
See here: https://bl.ocks.org/veltman/5cd1ba0b3c623e7b5146
Or... if you want to use media queries for font in SVG, the answer is yes. Run this code snippet.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="100%" height="200px">
<style>
text {
font-size: 10px;
}
#media (max-width: 600px) {
text {
font-size: 20px;
}
}
#media (max-width: 800px) {
text {
font-size: 16px;
}
}
</style>
<circle cx="50" cy="50" r="50" fill="orange"/>
<text x="50" y="60" text-anchor="middle">Testing</text>
</svg>
I actually found a relatively simple workaround.
using D3's scaleSqrt() you can do some math based on the pixel width that the svg is taking up.
For example if the svg viewbox width is 800, then when the svg has a width of 800px, the scale would be 1. When the pixel width of the svg is 400px, relative to the view box, that would be a scale of 1/2
scaleRatio = d3.scaleSqrt()
.domain([1600, 800, 600, 400, 200, 100])
.range([0.5, 1, 1.5, 2, 4, 8]);
const svgWidth = d3.select(svg).node().getBoundingClientRect().width;
someD3Element.attr('transform', `scale(${scaleRatio(svgWidth)})`);