How to get SVG dimentions to scale with screen size? - javascript

I've tried changing between <line> and <path> in case the percentage parameters made a difference. But I'm still getting the same issue where the <svg> won't line up with my <img>'s. My end goal is to basically have the 2 ends of the <svg> lock into the border of the <img>'s. Any advice would be amazing.
Pen
html:
<div class="svg-benefitsContainer">
<svg class="benefitSVG" height="500%" width="100%" preserveAspectRatio="none">
<line class="benefitSVG1" x1="15%" y1="15%" x2="20%" y2="32%" />
</svg>
</div>
<div>
<img src="https://static1.squarespace.com/static/59a7820e2994ca11766093d3/t/5a09f06d9140b7f3b7d84274/1510600813361/quality.png" class="benefitsImgMed" />
<img src="https://static1.squarespace.com/static/59a7820e2994ca11766093d3/t/5a09f014ec212d1131cf09fc/1510600724150/flash.png" class="benefitsImgLig" />
css:
body {
background-color: black;
}
.benefitsImgMed,
.benefitsImgLig,
.benefitsImgArr,
.benefitsImgNig {
position: absolute;
padding: 10px;
border-color: white;
border-width: 5px;
border-radius: 50%;
border-style: solid;
}
.benefitsImgMed {
margin-left: 8%;
margin-top: 6%;
width: 13%;
}
.benefitsImgLig {
margin-top: 32%;
margin-left: 19%;
width: 13%;
}
.benefitsImgArr {
margin-left: 37%;
margin-top: 3%;
width: 13%;
}
.benefitsImgNig {
margin-left: 66%;
margin-top: 18%;
width: 13%;
}
.svg-benefitsContainer {
width: 100%;
height: 500%;
}
.benefitSVG {
position: absolute
}
.benefitSVG1 {
fill: none;
stroke: white;
stroke-width: 5;
/*L 125 315 q -20 200 115 190*/
}

Because SVG percentages work differently to HTML percentages.
The <svg> width and height are relative to its parent container width and height respectively.
The <line> x and width are relative to the SVG viewport width.
The <line> y and height are relative to the SVG viewport height.
The <image> left and top are relative to the browser width.
If you want it to be reliable, the safest solution is to put all of the objects in an SVG file together. It's a lot simpler to understand also.
body{background-color:black;}
line, circle {
fill: black;
stroke: white;
stroke-width: 0.5;
}
<div class="svg-benefitsContainer">
<svg class="benefitSVG" height="100%" width="100%" viewBox="0 0 100 100">
<line class="benefitSVG1" x1="14.5" y1="12.5" x2="25.5" y2="38.5" />
<circle cx="14.5" cy="12.5" r="8"/>
<image xlink:href="https://static1.squarespace.com/static/59a7820e2994ca11766093d3/t/5a09f06d9140b7f3b7d84274/1510600813361/quality.png"
x="8" y="6" width="13" height="13"
class="benefitsImgMed"/>
<circle cx="25.5" cy="38.5" r="8"/>
<image xlink:href="https://static1.squarespace.com/static/59a7820e2994ca11766093d3/t/5a09f014ec212d1131cf09fc/1510600724150/flash.png"
x="19" y="32" width="13" height="13"
class="benefitsImgLig"/>
</svg>

Related

Cant align svg and <p> on the same line with display:inline-block?

Alright, im sure this is a simple solution but I can't get this to align here. I have generated HTML that looks like:
<div id = "innerCal">
<div id = "calCell"><p>[</p>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 447 443"><defs><filter x="-50%" y="-50%" width="200%" height="200%" id="Blur7"><feGaussianBlur stdDeviation="25" /></filter><g id="" data-name="Layer 1"><rect class="cls-1" width="900" height="758"/></g><g id="Img7"><path class="cls-1" d="M227.42,144.69v89.77c0,4.07,6.32,4.08,6.32,0V144.69C233.74,140.62,227.42,140.62,227.42,144.69Z"/><path class="cls-1" d="M221.19,146.76q2.69-3.33,5.6-6.47c.93-1,1.87-2,2.83-3l1.52-1.52.93,1.46,2.44,3.81,4.87,7.63a3.16,3.16,0,0,0,5.46-3.2l-5.6-8.76-2.92-4.58c-1.1-1.71-2.36-3.37-4.62-3.37-3.53,0-6.14,3.58-8.35,5.92s-4.52,5-6.64,7.56a3.28,3.28,0,0,0,0,4.48C217.83,147.87,220.1,148.09,221.19,146.76Z"/><path class="cls-1" d="M286.33,281.85c-.22-1.64-.35-3.28-.44-4.92v0l0-7.44a3.19,3.19,0,0,0-3.16-3.16,3.24,3.24,0,0,0-3.17,3.16,68.82,68.82,0,0,0,0,7.6q-10.76-7.95-21.45-16-6.1-4.57-12.25-9.12c-4.33-3.2-8.62-6.81-13.51-9.13a20,20,0,0,0-14.28-1.44c-5.47,1.48-10.79,3.85-16.1,5.82l-33.34,12.35-31.93,11.83L141,259.77a3.19,3.19,0,0,0-2.21-3.89c-1.83-.5-3.23.63-3.89,2.21q-2.76,6.57-5.53,13.13a2.39,2.39,0,0,0,0,1.8,18.53,18.53,0,0,0-.83,2.41A3.61,3.61,0,0,0,129,279a5.89,5.89,0,0,0,3.25,2.42c1.61.61,3.23,1.2,4.84,1.8l9.68,3.59a3.18,3.18,0,0,0,3.89-2.2,3.24,3.24,0,0,0-2.21-3.9l-8.06-3-1.29-.48,57.74-21.39,16.67-6.17c4.79-1.78,9.38-3.77,14.46-1.9,4.71,1.73,8.79,5.25,12.78,8.19s8.12,6,12.16,9q11.91,8.91,23.84,17.76l-5.91,2.16a3.16,3.16,0,0,0,1.68,6.1l6.82-2.49c2.52-.91,5.35-1.65,6.28-4.5,0-.07,0-.14.05-.21A2.42,2.42,0,0,0,286.33,281.85Z"/></g></defs><use style="fill:pink;" filter="url(#Blur7)" xlink:href="#Img7"transform="translate(0,0)"/><use style="fill:white;" xlink:href="#Img7"/></svg>
<p>]</p><h2>01-02-2020 10:00AM</h2></div></div>
This creates this, where the svg prevents the <p>'s from being all on the same line.
I want the <p>'s and the svg on the same line, with the h2 below:
Css:
#innerCal {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: -17px; /* Increase/Decrease this value for cross-browser compatibility */
overflow-y: scroll;
text-align: center;
}
#calCell {
//display: inline-block;
width: 150px;
}
#calCell > p {
display: inline-block;
}
#calCell > svg {
display: inline-block;
}
#calCell > h2 {
display: block;
text-transform: uppercase;
}
There will be many of these generated and I need them all to sit next to each other in line like a calendar. What is wrong here?
div#calCell is defined with a hard-coded width of 150px, whereas the SVG has no width attribute, but its viewbox' content exceed 150px.
defining an explicit width attribute to the SVG - so that the width of the SVG plus the two brackets does not exceeed 150px - solves the issue.
Demo in the snippet below.
Recommendations:
Fix the code's indentation
Do not use <p> for inline elements
Avoid having to use position:absolute
Always set explicit width and height attributes to the SVGs
#innerCal {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: -17px; /* Increase/Decrease this value for cross-browser compatibility */
overflow-y: scroll;
text-align: center;
}
#calCell {
width: 150px;
}
#calCell > svg {
display: inline-block;
}
#calCell > h2 {
text-transform: uppercase;
}
<div id = "innerCal">
<div id = "calCell">
<span>[</span>
<svg width="110px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 447 443">
<defs>
<filter x="-50%" y="-50%" width="200%" height="200%" id="Blur7"><feGaussianBlur stdDeviation="25" /></filter>
<g id="Img7" data-name="Layer 1"><rect class="cls-1" width="900" height="758"/></g><g id="Img7"><path class="cls-1" d="M227.42,144.69v89.77c0,4.07,6.32,4.08,6.32,0V144.69C233.74,140.62,227.42,140.62,227.42,144.69Z"/><path class="cls-1" d="M221.19,146.76q2.69-3.33,5.6-6.47c.93-1,1.87-2,2.83-3l1.52-1.52.93,1.46,2.44,3.81,4.87,7.63a3.16,3.16,0,0,0,5.46-3.2l-5.6-8.76-2.92-4.58c-1.1-1.71-2.36-3.37-4.62-3.37-3.53,0-6.14,3.58-8.35,5.92s-4.52,5-6.64,7.56a3.28,3.28,0,0,0,0,4.48C217.83,147.87,220.1,148.09,221.19,146.76Z"/><path class="cls-1" d="M286.33,281.85c-.22-1.64-.35-3.28-.44-4.92v0l0-7.44a3.19,3.19,0,0,0-3.16-3.16,3.24,3.24,0,0,0-3.17,3.16,68.82,68.82,0,0,0,0,7.6q-10.76-7.95-21.45-16-6.1-4.57-12.25-9.12c-4.33-3.2-8.62-6.81-13.51-9.13a20,20,0,0,0-14.28-1.44c-5.47,1.48-10.79,3.85-16.1,5.82l-33.34,12.35-31.93,11.83L141,259.77a3.19,3.19,0,0,0-2.21-3.89c-1.83-.5-3.23.63-3.89,2.21q-2.76,6.57-5.53,13.13a2.39,2.39,0,0,0,0,1.8,18.53,18.53,0,0,0-.83,2.41A3.61,3.61,0,0,0,129,279a5.89,5.89,0,0,0,3.25,2.42c1.61.61,3.23,1.2,4.84,1.8l9.68,3.59a3.18,3.18,0,0,0,3.89-2.2,3.24,3.24,0,0,0-2.21-3.9l-8.06-3-1.29-.48,57.74-21.39,16.67-6.17c4.79-1.78,9.38-3.77,14.46-1.9,4.71,1.73,8.79,5.25,12.78,8.19s8.12,6,12.16,9q11.91,8.91,23.84,17.76l-5.91,2.16a3.16,3.16,0,0,0,1.68,6.1l6.82-2.49c2.52-.91,5.35-1.65,6.28-4.5,0-.07,0-.14.05-.21A2.42,2.42,0,0,0,286.33,281.85Z"/></g>
</defs>
<use style="fill:pink;" filter="url(#Blur7)" xlink:href="#Img7"transform="translate(0,0)"/>
<use style="fill:black;" xlink:href="#Img7"/>
</svg>
<span>]</span>
<h2>01-02-2020 10:00AM</h2>
</div>
</div>
Try using position: absolute on your <p>
#calCell > p {
display: inline-block;
position: absolute;
}

How to create curve lines css div? [duplicate]

This question already has an answer here:
How to create a curved line with gradient?
(1 answer)
Closed 3 years ago.
I am using css, div only. I am trying to draw these type of lines :
.line {
width: 1px;
height: 100px;
background-color: black;
position: absolute;
border-radius: 50%/100px 100px 0 0;
}
#line1 {
top: 100px;
left: 50px;
}
#line2 {
top: 220px;
left: 150px;
height: 115px;
transform: rotate(120deg);
-webkit-transform: rotate(120deg);
-ms-transform: rotate(120deg);
}
<div class="line" id="line1"></div>
<div class="line" id="line2"></div>
I am trying to use border-radius: 50%/100px 100px 0 0; but no idea what is going wrong as nothing happens. Sorry for bad English,this is what i am trying to do. Please help.
You could use SVGs to achieve what you want.
See code below
Read more here -> SVG
<svg width="190" height="160" xmlns="http://www.w3.org/2000/svg">
<path d="M 5 50 C 40 10, 65 10, 75 40 S 100 100, 180 20" stroke="black" fill="transparent"/>
</svg>
EDIT: if you can't use SVG or other solutions besides div elements. and css you could use this.
If you can use ONLY 1 DIV element. Then use the below css on pseudo-elements before and after instead of line1 and line2
.line1 {
border-radius:100px 0 0 0 ;
border-width: 2px 0 0 2px;
margin-left:100px;
}
.line2 {
border-radius:0 0 100px 0 ;
border-width: 0 2px 2px 0 ;
}
.line {
border-color:red;
border-style: solid;
height:100px;
width: 100px;
}
<div class="line line1"></div>
<div class="line line2"></div>

How to make responsive text in SVG that scales to fit container

I have seen many things hinting at this possibility:
https://css-tricks.com/svg-text-typographic-designs/
SVG Scaling Text to fit container
http://www.petecorey.com/blog/2014/10/08/quest-for-scalable-svg-text/
https://discourse.wicg.io/t/auto-sizing-text-to-fit-container/1053/8
That first link is best, which shows how the text scales.
I have implemented a janky JavaScript version of this functionality, but I want to apply it to a lot of elements and I think SVG would be a better choice.
However, my attempt at copying the code from that first link doesn't end up with the same result, it doesn't work:
<head>
<style>
* {
padding: 0px;
margin: 0px;
}
/*div*/.ad-wrapper {
height: 0;
padding-top: 100%;
position: relative;
}
/*svg*/.ad {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
background: red;
color: black;
}
</style>
</head>
<body>
<div class="ad-wrapper">
<svg class="ad" xmlns="http://www.w3.org/2000/svg">
<text font-family="'proxima-nova', sans-serif">Mountain</text>
</svg>
</div>
</body>
Wondering what I'm doing wrong and how to fix it. I would like to have text centered in a responsive box (square even), where the padding on all sides of the text is proportionally the same as it scales up, without the need to use JavaScript at all.
Use always a viewBox attribute. A viewBox="0 0 100 100" will give you a square box. Give the text a x and a y. In this case you may use x="50" y="50" In order to center the text you may use text-anchor:middle;dominant-baseline:middle
* {
padding: 0px;
margin: 0px;
}
/*div*/.ad-wrapper {
height: 0;
padding-top: 100%;
position: relative;
}
/*svg*/.ad {
position: absolute;
width: 100%;
top: 0;
left: 0;
background: red;
color: black;
}
text{fill:black;text-anchor:middle;dominant-baseline:middle}
<div class="ad-wrapper">
<svg class="ad" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<text x="50" y="50" font-family="'proxima-nova', sans-serif">Mountain</text>
</svg>
</div>

How to create a square shaped div inside an arbitrary circle?

I am using Javascript to create an SVG element that contains a circle with a radius and a stroke thickness. The size and thickness may vary. I'm trying to create a square shaped div that would fit inside this SVG circle, so that I may add content inside the circle.
You can imagine the content to be anything from a text containing information about the circle, an anchor, or a button.
The rectangle must fit in the circle in so that all content is wrapped, and if there is no space, the content will be removed.
Here is the raw Sketch
<!-- A minified example of what the Javascript outputs -->
<svg viewBox="0 0 80 80" width="80" height="80">
<circle cx="40" cy="40" r="35"></circle>
</svg>
My main question is if it's possible to add this solely to the SVG element, and using something like the styling: left: 10%; top: 10%; width:50%; height: 50%, or if this would require more advanced CSS or Javascript trickery.
It's important to also mention that my circle has a radius of (svgWidth / 2) * 0.875 that is set from within the Javascript code.
Okay, thanks to #Sergiu I found the right mathematical equation to solve it, this was the primary issue. The code below is taken out of my Javascript code and shows how I create a rect that fits exactly like the square my image.
var squareSize = Math.sqrt(2) * radius - circleStrokeThickness;
var squareCenter = (svgWidth - squareSize) / 2;
this.rectangleContent = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
this.rectangleContent.setAttribute('x', squareCenter);
this.rectangleContent.setAttribute('y', squareCenter);
this.rectangleContent.setAttribute('width', squareSize);
this.rectangleContent.setAttribute('height', squareSize);
this.rectangleContent = $(this.rectangleContent).appendTo(this.svg);
This is not a div but it already answers all of the questions I had about the placement of the div.
I believe this is what you are looking for. You can resize the SVG and see everything resizes accordingly.
.container {
position: absolute;
top: 0;
bottom: 0;
right: 0;
left: 0;
background-color: #fff;
display: flex;
align-items: center;
justify-content: center;
}
.container svg {
fill: #dedede;
stroke: #000;
width: 200px;
height: 200px;
overflow: visible;
background-color: lightblue;
border: 1px solid blue;
}
.container svg g > .text-holder {
background-color: lightcoral;
}
.container svg g > .text-holder > p {
font-size: 12px;
}
.container svg g > circle {
cx: 50%;
cy: 50%;
r: 50%;
}
.container svg g > rect {
stroke: #f00;
x: 15%;
y: 15%;
width: 70%;
height: 70%;
}
<div class="container">
<svg viewBox="0 0 80 80">
<g>
<circle></circle>
<rect></rect>
<foreignObject class="text-holder" x="15%" y="15%" width="70%" height="70%">
<p xmlns="http://www.w3.org/1999/xhtml" style="font-size: 12px;">Text goes here</p>
</foreignObject>
</g>
</svg>
</div>

Hover-over Image function: how can I set its dimension by percentage and how to simplify this code?

I'm working with a image-effect code that achieves the following:
1) Combines background-blend-mode: multiply and filter: saturation 0%
2) Upon hovering over the image, the image reverts back to its original color palette.
I'm hoping you all can help me achieve the following goals:
1) How can I determine the image's width by percentage while the height is set to auto? Example: width: 50%; height: auto
2) How can I simplify this code so it isn't so chunky? I feel like this code can be structured more efficiently...
3) How can I make the width of the image correspond to the .page wrapper?
Here is a jsfiddle for visual / functional reference.
This is a Visualization of what I need help achieving
(Left: Current, Right: Goal)
Below is the code:
HTML:
<div class="page">
<div class="image-wrap-01">
<div class="image01">
<svg>
<defs>
<filter id="colorize_brown" color-interpolation-filters="sRGB">
<feFlood flood-color="#8E4204" result="A" />
<feColorMatrix type="saturate" in="SourceGraphic" values="0" result="B" />
<feBlend mode="multiply" in2="B" in="A" />
</filter>
</defs>
<image class="brown" filter="url(#colorize_brown)" x="0" y="0" width="100%" height="100%" xlink:href="http://i59.tinypic.com/1zvwwv9.jpg" />
</svg>
</div>
<p class="caption01">Image 001</p>
</div> <!-- END | image-wrap-01 -->
<div class="image-wrap-02">
<div class="image02">
<svg>
<defs>
<filter id="colorize_brown" color-interpolation-filters="sRGB">
<feFlood flood-color="#8E4204" result="A" />
<feColorMatrix type="saturate" in="SourceGraphic" values="0" result="B" />
<feBlend mode="multiply" in2="B" in="A" />
</filter>
</defs>
<image class="brown" filter="url(#colorize_brown)" x="0" y="0" width="100%" height="100%" xlink:href="http://i60.tinypic.com/nwzvpx.jpg" />
</svg>
</div>
<p class="caption02">Image 002</p>
</div> <!-- END | image-wrap-02 -->
</div> <!-- END | .page -->
CSS:
/* PAGE WRAP */
.page {
width: 50%;
height: 50%;
background-color: #ffecae;
}
/* IMAGE 01 */
.image-wrap-01 {
width: 100%;
height: 100%;
padding-top: 100px;
padding-bottom: 100px;
}
.image01, .image01 svg {
width: 600px;
height: 400px;
}
.image01 {
background: url("http://i59.tinypic.com/1zvwwv9.jpg");
background-size: 600px 400px;
position: relative;
}
/* IMAGE 02 */
.image-wrap-02 {
width: 100%;
height: 100%;
padding-top: 100px;
padding-bottom: 100px;
}
.image02, .image02 svg {
width: 400px;
height: 600px;
}
.image02 {
background: url("http://i60.tinypic.com/nwzvpx.jpg");
background-size: 400px 600px;
position: relative;
}
/* UNIVERSAL COMMAND */
.image01 svg, .image02 svg {
left: 0;
overflow: hidden;
position: absolute;
top: 0;
}
/* HOVEROVER */
.brown {
opacity: 1;
-webkit-transition: 0.5s ease-out;
-moz-transition: 0.5s ease-out;
-o-transition: 0.5s ease-out;
transition: 0.5s ease-out;
}
.brown:hover {
opacity: 0;
}
/* IMAGE CAPTIONS */
.caption01 {
text-align: left;
font: 13px/17px helvetica;
color: black;
width: 600px;
}
.caption02 {
text-align: right;
font: 13px/17px helvetica;
color: black;
width: 400px;
}
I believe this answers your question:
The images are now the full width of the column. The only thing you need to manually code in is the aspect ratio of the image as padding-top:150%;, which is the same as the responsive solution for embedding youtube/vimeo videos into a website.
http://jsfiddle.net/ryanpither/6x0apqod/
Let me know if I interpreted your question wrong.

Categories

Resources