Positioning overlapping SVGs inside a block element - html

I have a couple of circle SVGs that I am stacking on top of one another. In order to do that I have assigned them an absolute position style. My problem is I can't seem how to get the stacked SVGS to display within a block element, such as a DIV tag, when I do so.
This is what I have so far:
.card {
background-color:white;
border: 1px solid gray;
border-top: 10px solid gray;
padding:20px;
box-shadow: 1px 1px 1px #888888;
margin-bottom: 30px;
}
circle {
fill: transparent;
stroke-width: 30;
}
svg {
width: 150px;
height: 150px;
position: absolute;
}
<P>I would like to have the three pie charts stack on top of them like they are doing, but I would like for them to be inside the card (DIV).</P>
<DIV class="PieChart" style="stroke-dasharray: 377 377; stroke: #80F162;">
<svg>
<circle r="60" cx="50%" cy="50%"/>
</svg>
</DIV>
<DIV class="PieChart" style="stroke-dasharray: 255 377; stroke: #F06161;">
<svg>
<circle r="60" cx="50%" cy="50%"/>
</svg>
</DIV>
<DIV class="PieChart" style="stroke-dasharray: 189 377; stroke: #F4F464;">
<svg>
<circle r="60" cx="50%" cy="50%"/>
</svg>
</DIV>
An example of what I have so far can be found here:
https://jsfiddle.net/e82agLn2/
Any help would be greatly appreciated.
Thanks!

The reason this is happening is that you have 3 svg nodes that you're overlapping using position:absolute (and absolute positioning takes svg elements out of the wrapping div's flow);
You could use one svg tag( without position:absolute ) and use g tags to group the elements_
fiddle

Related

Start svg polyline exactly at right border of span element

I have a simple html file containing an SVG polyline:
Here's my code:
span {
border: 1px solid red;
}
polyline{
fill:none;
stroke:red;
stroke-width:3
}
<p>A block element containing an <span>inline element</span></p>
<svg height="200" width="500">
<polyline points="0,0 20,0 40,25" />
</svg>
I would like to start the polyline exactly at the midpoint of my span's right border. How can I do that?
This is a very basic idea: you give the svg position:absolute and the same size as the html element overlapped. You calculate the bounding client rect of the span and the position of the point where the polyline shpuld begin. Ypu either translate the polyline or you rewrite the points attribute so that it begins where you want it
let bcr = sp.getBoundingClientRect();
poly.setAttribute("transform",`translate(${bcr.x+bcr.width},${bcr.y+bcr.height/2})`)
svg {
outline: solid;
position: absolute;
top:0;left:0;
}
div {
width: 500px;
height: 200px;
}
span {
border: 1px solid red;
}
polyline {
fill: none;
stroke: red;
stroke-width: 3;
}
<div>
<p>A block element containing an <span id="sp">inline element</span></p>
</div>
<svg height="200" width="500">
<polyline id="poly" points="0,0 20,0 40,25" />
</svg>

HTML arc sector with inline style

I would like to use HTML + CSS to draw a arc sector with fixed radix and length (e.g. 30px radius and 70% length).
I found so far most of the solution is to combined two pictures with position:absoulte. Unfortunately, my html codes will be embedded as an email template to send out, and I found that Gmail does not support absolute position. And that is also the reason why I would like to use inline style rather than header css.
Related question here:
HTML5 / CSS3 Circle with Partial Border
The similar output I am looking for.
http://dabblet.com/gist/3949571
Any help for it?
I'd use an SVG.
svg {
width: 150px;
height: 150px;
}
circle.inner {
stroke: rebeccapurple;
stroke-width: 3;
stroke-dasharray: 39% 139%;
stroke-dashoffset: 78%;
fill: pink;
}
<svg viewbox="0 0 100 100">
<circle class="inner" cx="40" cy="40" r="25" />
</svg>
you can use transparent borders and inset shadow to draw bg color :
/*demo*/
div {
display:flex;
align-items:center;
justify-content:center;/* center content not text */
text-align:center;
}
<div style="
box-sizing:border-box;
padding:1px;
margin:5px;
height:200px;
width:200px;
border:solid 20px transparent;
border-top-color:blue;
box-shadow:inset 0 0 0 100px lightblue;
border-radius:100%;"
>Some text <br/> too?</div>

Create three lines following element using pseudo class/elements

I'm trying to get a heading element on my page to look like:
I saw the steps shown at CSS: :before and :after pseudo elements in practice (see heading 'Styling titles') which displays a single line before and after the heading element. I liked that idea and wanted to expand it out to display three lines as per the sample image. Unlike image I was hoping for the lines to be thinner and not take up the full height space available but that's all I could mock up with limited tools/skills.
My issue is not getting three lines, but rather aligning each of those lines to their intended place. Currently they mess up and stack in an unexpected way (at least unexpected from my understanding).
Here is a JsFiddle showing my progress so far. I've created the h1 for text and two spans either side of the text but within the h1. My reasoning for this was to remove the single line from the h1 and apply the three lines via each span utilising pseudo-elements :after and :before for two of them.
Not sure where I have gone wrong or if it is even possible. I have complete access to HTML and CSS so the structure and styles are not locked down.
Let me know if I haven't been clear.
You can do it using two spans.
.long {
position: relative;
width: 100%;
}
.long:after, .long:before {
content: '';
position: absolute;
height: 3px;
width: 30px;
background: black;
top: 50%;
left: -34px;
}
.long:before {
left: calc(100% + 4px);
}
.title {
position: relative;
font-size: 50px;
margin-left: 40px;
}
.title:after, .title:before {
content: '';
position: absolute;
height: 20%;
width: 20px;
border-top: 3px solid black;
border-bottom: 3px solid black;
top: calc(100% - 31.2%*2);
right: -24px;
}
.title:before {
right: calc(100% + 4px)
}
<span class="title"><span class="long">text</span></span>
Also, possible with svg if you want round corners.
<svg width="170" height="50" viewBox="-10 0 170 50">
<defs>
<line id="small" x1="3" y1="3" x2="20" y2="3" stroke="black" stroke-width="3" stroke-linecap="round" />
<line id="large" x1="3" y1="3" x2="30" y2="3" stroke="black" stroke-width="3" stroke-linecap="round" />
</defs>
<text x="75" y="35" text-anchor="middle" font-size="50">text</text>
<use transform="translate(5,10)" xlink:href="#small" />
<use transform="translate(-5,17)" xlink:href="#large" />
<use transform="translate(5,24)" xlink:href="#small" />
<use transform="translate(125,10)" xlink:href="#small" />
<use transform="translate(125,17)" xlink:href="#large" />
<use transform="translate(125,24)" xlink:href="#small" />
</svg>
You could use a CSS background image, or gradient to achieve the same effect.
The CSS background will be something along the lines of:
background:linear-gradient(to bottom, #fff 0%, #fff 20%, transparent 20%, transparent 40%, #fff 40%, #fff 60%, transparent 60%, transparent 80%, #fff 80%, #fff 100%);
Why not create a left and right image and display it with the :before and :after like you are but instead of setting content: add background: url('img_left.png');?
Here is a Fiddle to show what I mean.

Fill SVG on parent div hover (no JS)

I have 2 SVG paths and I would like them to change fill color when users rollover their parents did. I can get the hover working but only when users hover on the svg. I know it is easy with JS but I would prefer to stick with CSS.
<div class="button">
<svg width="100px" height="100px">
<circle cx="30" cy="30" r="20" style="stroke: black;"/>
</svg>
</div>
<div class="button">
<svg width="100px" height="100px">
<circle cx="30" cy="30" r="20" style="stroke: black;"/>
</svg>
</div>
CSS:
.button{
background-color:gray;
margin-bottom: 20px ;
}
svg{
fill:green;
}
svg:hover{
fill:blue;
}
Demo: http://jsfiddle.net/69g7K/
We can do this, by using parent:hover as selector to vary the CSS attributes of child1 and child2 which are within their respective parents..
Use the following for the CSS :
.button:hover .svg1{
fill:blue;
}
.button:hover .svg2{
fill:yellow;
}
Demo : jsFiddle
here is a trick if you have a more complex svg element, for instance if you have multiple paths, do the following:
<div class="your-class">
<svg [svg content...]
<path ...>
<path ...>
<path ...>
</div>
use css to look for paths not only something inside a specific path:
.your-class{
/* code without rover */
transition: 0.3s ease-in-out;
}
.your-class:hover path{
stroke: #C4C4C4; /* use stroke to color svg lines*/
/* use fill to color the inside */
also (maybe worth mentioning) if you your div to be only around the svg you can use the width: fit-content; for your div
hope it helps you out
svg {
fill: #444;
}​
just add a class to each SVG and use the css above something like this:
svg.svg1:hover {
fill: #666;
}​
svg.svg2:hover {
fill: #666;
}​
remove style="fill: yellow" for example from each SVG path otherweise it will overwrite your css
<svg class=svg1 width=150px height=150px>
<circle cx=64 cy=64 r=20>
</svg>
<svg class=svg2 width=150px height=150px>
<circle cx=64 cy=64 r=20>
</svg>
Demo:http://jsfiddle.net/GwWk5/
svg {
fill: red;
}
svg.svg1:hover {
fill: blue;
}
svg.svg2:hover {
fill: green;
}

How to make arc shapes with CSS3?

I'm trying to achieve following look, with pure css:
Where each white arc is a different element, say span. I know we can make round shapes with css, but how can it be turned into arc sort of shape?
With the following HTML:
<div id="arcs">
<div>
<div>
<div>
<div></div>
</div>
</div>
</div>
</div>
And the CSS:
#arcs div {
border: 2px solid #000; /* the 'strokes' of the arc */
display: inline-block;
min-width: 4em; /* the width of the innermost element */
min-height: 4em; /* the height of the innermost element */
padding: 0.5em; /* the spacing between each arc */
border-radius: 50%; /* for making the elements 'round' */
border-top-color: transparent; /* hiding the top border */
border-bottom-color: transparent;
}
#arcs div {
border: 2px solid #000;
/* the 'strokes' of the arc */
display: inline-block;
min-width: 4em;
/* the width of the innermost element */
min-height: 4em;
/* the height of the innermost element */
padding: 0.5em;
/* the spacing between each arc */
border-radius: 50%;
/* for making the elements 'round' */
border-top-color: transparent;
/* hiding the top border */
border-bottom-color: transparent;
}
<div id="arcs">
<div>
<div>
<div>
<div></div>
</div>
</div>
</div>
</div>
JS Fiddle demo.
SVG Approach:
I would recommend you to use SVG to draw such shapes:
In the example below I've used SVG's path element to draw an arc. This element takes single attribute d to describe the shape structure. d attributes takes a few commands and corresponding necessary parameters.
I've used only 2 path commands:
M command is used to move the pen to a specific point. This command takes 2 parameters x and y and usually our path begins with this command. It basically defines starting point of our drawing.
A command which is used to draw curves and arcs. This commands takes 7 parameters to draw an arc / curve. A detailed explanation of this command is Here.
Screenshot:
Useful Resources:
Specification
MDN
Working Example:
svg {
width: 33%;
height: auto;
}
<svg viewBox="0 0 300 300" xmlns="http://www.w3.org/2000/svg">
<defs>
<g id="arcs" fill="none" stroke="#fcfcfc">
<path d="M80,80 A100,100,0, 0,0 80,220" stroke-width="4" />
<path d="M90,90 A85,85,0, 0,0 90,210" stroke-width="3.5" />
<path d="M100,100 A70,70,0, 0,0 100,200" stroke-width="3" />
<path d="M110,110 A55,55,0, 0,0 110,190" stroke-width="2.5" />
</g>
</defs>
<rect x="0" y="0" width="300" height="300" fill="#373737" />
<use xlink:href="#arcs" />
<use xlink:href="#arcs" transform="translate(300,300) rotate(180)" />
</svg>