Issue perfectly masking a div using an SVG frame - svg

I'm trying to mask a div with an SVG 'frame'. Despite positioning the SVG absolutely and setting height/width to 100%, there's still slivers of the parent div visible around the bottom and right edges.
html
<div class="container">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="-144 2 502 609" style="enable-background:new -144 2
502 609;" xml:space="preserve" preserveAspectRatio="none">
<style type="text/css"></style>
<path class="st0" d="M-144,2v608h501.2V2H-144z M354.5,608.5l-
496.2-12.2C-147,201.8-62.3,4.5,112.5,4.5S367.8,205.8,354.5,608.5z"
/>
</svg>
</div>
css
html,
body {
height: 100%;
width: 100%;
margin:0;
padding:0;
}
.container {
width: 50%;
height: 50%;
top: 25%;
margin:auto;
background: pink;
position: relative;
}
svg {
position: absolute;
top:0;
left:0;
height: 100%;
width: 100%;
}
.st0{
fill: white;
}
https://jsfiddle.net/samseurynck/b2x58ahc/
I'd like the white SVG shape to completely mask out the pink div behind it, with no slivers of the div showing (on the bottom and right sides) like it is now. The slivers seem to scale up with the browser. I'm curious if this is even possible with SVG if the way I've tried it isn't working.

I've made a few changes to the path. While the viewBox="-144 2 502 609"the path goes to 501.2 instead of 502 (in x) and to 608.5 instead of 609 (in y). I've changed those numbers in your path.
html,
body {
height: 100%;
width: 100%;
margin:0;
padding:0;
}
.container {
width: 50%;
height: 50%;
top: 25%;
margin:auto;
background: pink;
position: relative;
}
svg {
position: absolute;
top:0;
left:0;
height: 100%;
width: 100%;
}
.st0{
fill: white;
}
<div class="container">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="-144 2 502 609" style="enable-background:new -144 2 502 609;" xml:space="preserve" preserveAspectRatio="none">
<style type="text/css">
</style>
<path class="st0" d="M-144,2v609h502V2H-144z M354.5,609l-496.2-12.2C-147,201.8-62.3,4.5,112.5,4.5S367.8,205.8,354.5,609z"
/>
</svg>
</div>

Related

Why is SVG width 0 if container is display flex?

When I run the following code in a browser:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<style>
svg {
border:1px solid green;
width:200px !important;
height:200px;
}
#container {
position:fixed;
top:300px;
left:800px;
width:1px;
height:1px;
overflow:visible;
display:flex;
flex-wrap:wrap;
justify-content:center;
align-content:center;
}
</style>
</head>
<body>
<div id="container">
<svg class="e3" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="50"/>
</svg>
</div>
</body>
</html>
All I get is a 2 pixel vertical line in the browser. It seems the width of my SVG is 0 (not including the green borders). When I delete the css rule display:flex, then my SVG circle appears. I tried to force my SVG to have a width: 200px !important; but this rule doesn't seem to take effect.
Why is my SVG not respecting the 200px rule when I use display:flex on the container?
I believe your SVG node is not displaying as you expect because it has a default position of static. If you change the SVG node to be absolute you'll get the desired behavior.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<style>
svg {
position: absolute;
border: 1px solid green;
width: 200px;
height: 200px;
}
#container {
position: fixed;
/* changed these for ease of viewing */
top: 30px;
left: 150px;
width: 1px;
height: 1px;
overflow: visible;
display: flex;
flex-wrap: wrap;
justify-content: center;
align-content: center;
border: 1px solid red;
}
</style>
</head>
<body>
<div id="container">
<svg class="e3" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="50"/>
</svg>
</div>
</body>
</html>

Creating a SVG image tooltip

hi guys i need some help i need to create a tooltip with an image inside it however this is for an svg map so i cant use divs like in css and html.I have managed to create an image tooltip .However only one image can appear when i hover on all elements how can i make different images appear for different svg elements ? this is the code i have used for my tooltip:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" onload="init(evt)" width="380" height="100">
<style>
.caption{
font-size: 14px;
font-family: Georgia, serif;
}
.tooltip{
font-size: 12px;
}
.tooltip_bg{
fill: white;
stroke: black;
stroke-width: 1;
opacity: 0.85;
}
</style>
<script type="text/ecmascript">
<![CDATA[
function init(evt)
{
if ( window.svgDocument == null )
{
svgDocument = evt.target.ownerDocument;
}
tooltip = svgDocument.getElementById('tooltip');
tooltip_bg = svgDocument.getElementById('tooltip_bg');
}
function ShowTooltip(evt, mouseovertext)
{
tooltip.setAttributeNS(null,"x",evt.clientX+11);
tooltip.setAttributeNS(null,"y",evt.clientY+27);
tooltip.setAttributeNS(null,"visibility","visible");
length = tooltip.getComputedTextLength();
tooltip_bg.setAttributeNS(null,"width",length+8);
tooltip_bg.setAttributeNS(null,"x",evt.clientX+8);
tooltip_bg.setAttributeNS(null,"y",evt.clientY+14);
tooltip_bg.setAttributeNS(null,"visibility","visibile");
}
function HideTooltip(evt)
{
tooltip.setAttributeNS(null,"visibility","hidden");
tooltip_bg.setAttributeNS(null,"visibility","hidden");
}
]]>
</script>
<text class="caption" x="10" y="35">Mouseover a square</text>
<text class="caption" x="10" y="50">to display a tooltip</text>
<rect id="rect1" x="160" y="10" width="60" height="60" fill="blue"
onmousemove="ShowTooltip(evt)"
onmouseout="HideTooltip(evt)"/>
<rect id="rect2" x="240" y="10" width="60" height="60" fill="green"
onmousemove="ShowTooltip(evt)"
onmouseout="HideTooltip(evt)"/>
<rect class="tooltip_bg" id="tooltip_bg"
x="0" y="0" rx="4" ry="4"
width="55" height="17" visibility="hidden"/>
<image xlink:href="Blooper-icon.png" class="tooltip" id="tooltip"x="0" y="0"height="50px"width="50px"visibility="hidden"/>
</svg>
in HTML
<div class="svgTooltip"></div>
<svg>
<path class="tempClass" .......>
</path>
</svg>
in CSS
.svgTooltip {
pointer-events: none;
position: absolute;
font-size: 15px;
text-align: center;
background: white;
padding-bottom: 5px;
padding-left: 5px;
padding-right: 5px;
z-index: 5;
height: 30px;
line-height: 30px;
margin: 0 auto;
color: #21669e;
border-radius: 5px;
box-shadow: 0 0 0 1px rgb(122, 92, 92);
display: none;
}
.svgTooltip::after {
content: "";
position: absolute;
left: 50%;
top: 100%;
width: 0;
height: 0;
margin-left: -10px;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
border-top: 10px solid rgb(122, 92, 92);
}
.active {
display: block;
}
in JS
$(function() {
$tooltip = $(".svgTooltip");
$(".tempClass").hover(
function() {
$tooltip.addClass("active");
$tooltip.html($(this).attr("title"));
},
function() {
$tooltip.removeClass("active");
}
);
});
$(document).on("mousemove", function(e) {
$tooltip.css({
left: e.pageX - 30,
top: e.pageY - 70
});
});

SVG Responsive Text

I have an SVG within a web page, it consists of images + text
<object data="/infographic/timeline.svg" type="image/svg+xml">
<img src="/infographic/timeline.svg" alt="Timeline">
</object>
All the images are responsive, but the text isn't, so the text becomes really, REALLY small.
snippet of SVG (its massive)
<defs>
<style>
.cls-1 {
font-size: 60.014px;
}
.cls-1, .cls-10 {
opacity: 0.69;
}
.cls-1, .cls-10, .cls-4, .cls-5, .cls-7, .cls-8, .cls-9 {
fill: #ffffff;
}
.cls-1, .cls-10, .cls-3, .cls-4, .cls-5, .cls-6, .cls-7, .cls-9 {
text-anchor: middle;
}
.cls-1, .cls-3, .cls-6 {
font-family: "Roboto";
}
.cls-2 {
font-size: 32.014px;
}
.cls-3 {
font-size: 14.089px;
}
.cls-3, .cls-6 {
fill: #db7426;
}
.cls-4, .cls-6 {
font-size: 32px!important;
}
.cls-10, .cls-4, .cls-5, .cls-7, .cls-8, .cls-9 {
font-family: Roboto;
}
.cls-5 {
font-size: 24px;
}
.cls-5, .cls-8, .cls-9 {
font-weight: 400;
}
.cls-6 {
font-weight: 600;
}
.cls-10, .cls-7 {
font-size: 18.75px;
font-weight: 300;
}
.cls-7 {
opacity: 0.4;
}
.cls-8, .cls-9 {
font-size: 22px;
}
</style>
</defs>
<text id="Who_are_you_what_do_you_do_what_s_your_why_What_s_been_keepi" data-name="Who are you, what do you do, what’s your why? What’s been keepi" class="cls-8" x="397.706" y="535.325">Who are you, what do you do, what’s your why?<tspan x="397.706" dy="26.4">What’s been keeping you lying awake at night. </tspan></text>
Is there anyway I can get the text size to increase as the SVG/screen width gets smaller?
Any help would be greatly appreciated.
It's not possible with pure SVG (at least not yet). The only solution would be to either:
inline the SVG and manipulate the size of the text with javascript.
inline the SVG and control the size of the text with media queries (see below).
Add CSS to the SVG and use media queries there (see below).
use media queries to switch SVGs when the page gets small
Example of option 2: Using media queries with inlined SVGs
text {
font-size: 10px;
}
#media (max-width: 400px) {
text {
font-size: 20px;
}
}
<svg viewBox="0 0 100 100" width="100%" height="100%">
<circle cx="50" cy="50" r="50" fill="orange"/>
<text x="50" y="60" text-anchor="middle">Testing</text>
</svg>
Example of option 3: Using media queries in CSS in the SVGs
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="100%" height="100%">
<style>
text {
font-size: 10px;
}
#media (max-width: 400px) {
text {
font-size: 20px;
}
}
</style>
<circle cx="50" cy="50" r="50" fill="orange"/>
<text x="50" y="60" text-anchor="middle">Testing</text>
</svg>
This is possible using the foreignObject svg element in a html context and some adjustment of the viewBow.
On this demos, the text stay selectable:
.demo {
overflow: auto;
resize: both;
border:1px black solid;
width: 230px;
height: 130px
}
.svgtext {
font-size: 28rem;
height:100%;
width:100%
}
<div class="demo">
<svg x="0" y="30" viewBox="0 0 100 100" width="100%" height="100%">
<foreignObject x="12" y="23" height="100%" width="100%">
<div class"svgtext">
Hello world!
</div>
</foreignObject>
</svg>
</div>
Use preserveAspectRatio to control the resizing behavior:
.demo {
overflow: auto;
resize: both;
border:1px black solid;
width: 230px;
height: 130px
}
.svgtext {
font-size: 28rem;
height:100%;
width:100%
}
<div class="demo">
<svg preserveAspectRatio="none" x="0" y="30" viewBox="0 0 100 100" width="100%" height="100%">
<foreignObject x="12" y="23" height="100%" width="100%">
<div class"svgtext">
Hello world!
</div>
</foreignObject>
</svg>
</div>

How to make SVG break aspect ratio

I have and SVG and I need to fulfil the browser windows. It´s an with sag assigned to src attribute. No mather I do, always keep aspect ratio. I even force image width and height via CSS but I can´t make it work.
The url: https://dl.dropboxusercontent.com/u/814218/svg/svg_test.html
Any suggestion?
Finally, I find the solution by recommendation of #SVG IRC Mozilla Group. The related info is here: http://codepen.io/jonitrythall/blog/preserveaspectratio-in-svg
I need to use, viewBox and preserveAspectRatio attributes. That´s the solution.
Here the final sample SVG source code:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 1282 802" preserveAspectRatio="defer none"
xml:space="preserve">
<polygon opacity="0.2" fill="#FF00FF" stroke="#93278F" stroke-miterlimit="10" points="-1.5,0 -1.5,800 638.5,400 "/>
<polygon opacity="0.2" fill="#009245" points="0,801 1280,801 640,401 "/>
<polygon opacity="0.2" fill="#FFFF00" stroke="#FFFF00" stroke-miterlimit="10" points="638.5,400 1278.5,800 1278.5,0 "/>
</svg>
Try using:
.autoHeight{
width: 100%;
height: 100%;
}
#bg img {
max-width: 100%;
width: 100%;
height: 100%;
}
And your html should looks like:
<body cz-shortcut-listen="true">
<div id="bg" class="autoHeight" style="width: 100%; height: 100%;">
<img class="autoHeight" src="triangles.svg" alt="" style="width: 100%; height: 100%;">
</div>
</body>
But, basically, you need use: for both, width and height: 100%
Do you mean you need something like this?
<html>
<head>
<style>
html, body, img#svg { width: 100%; height: 100%; border: 0; margin: 0; padding:0 }
</style>
</head>
<body>
<img id="svg" src="https://dl.dropboxusercontent.com/u/814218/svg/triangles.svg" />
</body>
</html>

SVG scales down to fit small screen height, why?

I have a simple SVG in a web page, and I'd like the SVG to be responsive to width only. The problem is, it scales down also when the screen height is less than the SVG height.
HTML:
<div class="container">
<svg version="1.1" width="100%" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500" preserveAspectRatio="xMinYMin">
<circle stroke="#000" stroke-width="10" fill="transparent" cx="250" cy="250" r="200"/>
</svg>
</div>
CSS:
svg {
max-height: 100%;
}
.container {
width:50%;
border: 1px solid black;
}
Here is the jsfiddle, where you can see the circle radius decreases when the window height is reduced. How can this be avoided ?
Thanks !
Here is what I wanted to achieve, sorry if my question wasn't clear enough:
width of the SVG depending only on the width left available to the container,
(width / height) ratio of the SVG preserved at all time,
container's height depending only on the width of the SVG and its (width / height) ratio.
I got it working this way:
HTML & SVG:
<div class="container">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 500 400" preserveAspectRatio="xMinYMin">
<circle fill="#F7941E" stroke="#231F20" stroke-width="10" cx="250" cy="200" r="150"/>
</svg>
</div>
<hr>
CSS:
.container {
position: relative;
width:50%;
padding-bottom: 40%;
border: 1px solid black;
}
svg {
position: absolute;
top: 0;
left: 0;
max-height: 100%;
}
Fiddle here
The only drawback I see is that the padding-bottom of the container needs to be defined, and to a value matching the w/h ratio of the SVG, which is redundant.
If what you want is for the circle to remain the same size even when the window size changes, then just get rid of the viewBox. Try removing : viewBox="0 0 500 500" preserveAspectRatio="xMinYMin" from the opening svg tag.
The default for height (like width) is 100%. Which means 100% of it's container height.
One solution is to give the container a very large height.
.container {
width:50%;
height: 9999px;
border: 1px solid black;
}
Fiddle here
You don't really say what you want to happen to the lower parts of the circle when the height scales up. If you want it to be hidden off the bottom of the div container, then you could do something like this:
svg {
height: 9999px;
}
.container {
width:50%;
height: 300px;
overflow: hidden;
border: 1px solid black;
}
Fiddle here

Resources