How to modify a CSS value when it's nested? - javascript

I can change the top property of percent1 with
document.getElementById('percent1').style.top = '50px';
HTML:
<div class="box" id="box1">
<div class="percent" id="percent1">
<svg>
<circle cx="70" cy="70" r="70"></circle>
<circle cx="70" cy="70" r="70"></circle>
</svg>
<div class="num">
<h2>45<span>%</span></h2>
</div>
</div>
<h2 class="text">Percentage</h2>
</div>
CSS to modify:
.box .percent svg circle:nth-child(2)
{
stroke-dashoffset:calc(440 - (440 * 15) / 100);
}
How can I change "stroke-dashoffset" value when it's nested like this?

It would appear :nth-child targeting matches elements based upon their position, not on their properties so I think what you want isn't possible with this approach.
Could consider attaching some other type of targeting mechanism (either in HTML or JS) to target the element you want to style more granularly in CSS.
#percent1 {
position: absolute;
top: 50px;
}
#percent1>svg {
overflow: visible;
}
#percent1>svg>circle {
fill: blue;
}
#percent1>svg>circle:nth-child(2) {
fill: yellow;
}
#circle-target {
stroke-dashoffset: 100;
stroke: red;
stroke-width: 8px;
}
<div class="box" id="box1">
<div class="percent" id="percent1">
<svg>
<circle cx="70" cy="70" r="70"></circle>
<circle cx="70" cy="70" r="70" id="circle-target"></circle>
</svg>
</div>

You can do it with
document.querySelectorAll(".box .percent svg circle:nth-child(2)")

Related

Add a tick selected css

.showcase-components-colorlist color {
border: 2px solid transparent;
margin: 1px;
padding: 2px;
border-radius: 50%;
cursor: pointer;
}
<div class="showcase-components-colorlist color showcase-components-colorlist color-- active">
<svg width="40" height="40">
<circle cx="20" cy="20" r="19" fill="#c5145d" stroke="#fff" stroke-width="1"></circle>
</svg>
</div>
<div class="showcase-components-colorlist color">
<svg width="40" height="40">
<circle cx="20" cy="20" r="19" fill="#db2586" stroke="#fff" stroke-width="1"></circle>
</svg>
</div>
How to add a check mark to one of the circles as generated by the code above.
One way to do this is through pseudo content. You need to give the element which you'll set the pseudo content a relative container. Then, you create your pseudo content (in this case, a check mark). The positioning will be relative to the parent element's dimensions.
.showcase-components-colorlist {
border: 2px solid transparent;
margin: 1px;
padding: 2px;
border-radius: 50%;
cursor: pointer;
position: relative;
}
.showcase-components-colorlist.selected::before {
content: '✅';
position: absolute;
left: 11px;
top: 9px;
}
<div class="showcase-components-colorlist color showcase-components-colorlist color-- active">
<svg width="40" height="40"><circle cx="20" cy="20" r="19" fill="#c5145d" stroke="#fff" stroke-width="1">
</circle>
</svg>
</div>
<div class="showcase-components-colorlist selected">
<svg width="40" height="40">
<circle cx="20" cy="20" r="19" fill="#db2586" stroke="#fff" stroke-width="1"></circle>
</svg>
</div>
Create your own <svg-option> Native JavaScript Web Component.
<svg-option></svg-option>
<svg-option fill="red" selected></svg-option>
<svg-option fill="rebeccapurple" selected-fill="yellow" selected></svg-option>
creates:
<script>
customElements.define("svg-option",class extends HTMLElement{
connectedCallback(){
this.style.display = "inline-block";
this.innerHTML=`<svg viewBox="0 0 50 50">
<circle cx="50%" cy="50%" r="49%" fill="${this.getAttribute("fill") || "green"}"/>
<circle cx="50%" cy="50%" r="30%" fill="${this.getAttribute("selected-fill") || "beige"}" visibility="hidden"/>
</svg>`;
this.select();
this.onclick = (evt) => this.toggle();
}
select(state = this.hasAttribute("selected")) {
this.querySelector("circle:nth-child(2)").setAttribute("visibility" , state ? "visible" :"hidden");
}
toggle(){
this.select( this.toggleAttribute("selected") );
}
})
</script>
<style>
svg-option {
--svg-option-size:180px;
width: var(--svg-option-size);
height: var(--svg-option-size);
cursor: pointer;
}
svg-option[selected]{
background:lightgreen;
}
svg-option:not([selected]){
background:pink;
}
</style>
<svg-option></svg-option>
<svg-option fill="red" selected></svg-option>
<svg-option fill="rebeccapurple" selected-fill="yellow" selected></svg-option>

Scrolling with multiple SVGs

I am trying to create 4 svg based charts one below another.
After charts are loaded, I can see only 2 and half charts which get occupied on web browser without scrolling.
I can see scroll bars enabled in left and at the bottom but they don't scroll much.
<div overflow="auto">
<svg id="chart1" style="overflow-y:scroll"></svg>
<svg id="chart2" style="overflow-y:scroll"></svg>
<svg id="chart3" style="overflow-y:scroll"></svg>
<svg id="chart4" style="overflow-y:scroll"></svg>
</div>
Above are 4 svg and below is the css for each of them.
#chart1 {
width: 100%;
height: 100%;
position: absolute;
}
When I minimize the webpage, I can see 4 charts otherwise 2 and half only.
What all I have tried:
1. enabling auto-scroll for html, body
2. enabling scroll in svg (similar to above code).
3. increasing html and body height and width.
html, body {
width: 100%;
height: 200%;
margin: 0px;
padding: 0px;
}
Here is a example on jsfiddle, each svg has a data-no, and one common class. It is more easy with this example for you to explain what you expect exactly...
https://jsfiddle.net/ericsm/ondtxmp2/
and here the code too :
each svg take 100% of body.
<HTML>
<HEAD>
<style type="text/css">
.container-charts {
border:solid 8px blue;
div : 100%;
}
.chart {
width: 100%;
height: 100%;
border:dashed 2px green;
}
html, body {
margin: 0px;
padding: 0px;
}
</style>
</HEAD>
<BODY>
<div class="container-charts" overflow="auto">
<svg class="chart" data-no="1">
<ellipse cx="100" cy="80" rx="100" ry="50" style="fill:yellow;stroke:purple;stroke-width:2" />
</svg>
<svg class="chart" data-no="2">
<ellipse cx="100" cy="80" rx="100" ry="50" style="fill:blue;stroke-width:2" />
</svg>
<svg class="chart" data-no="3">
<ellipse cx="100" cy="80" rx="100" ry="50" style="fill:gray;stroke-width:2" />
</svg>
<svg class="chart" data-no="3">
<ellipse cx="100" cy="80" rx="100" ry="50" style="fill:black;stroke-width:2" />
</svg>
</div>
</BODY>
</HTML>

WordPress - Onclick functions not working in <a> tag

I am creating a sliding sidebar menu for my WordPress site using only HTML/CSS/JavaScript. This is from a tutorial from YouTube and followed everything exactly. The issue is that when I click on the buttons, the error reads "Uncaught ReferenceError: openSlideMenu is not defined
at HTMLAnchorElement.onclick". I get the same error for the other button. See code below.
HTML (blog.php)
<nav class="navbar">
<div class="side-menu">
<span class="open-slide">
<a href="#" onclick="openSlideMenu()">
<svg width="30" height="30">
<path d="M0,5 30,5" stroke="#000" stroke-width="5" />
<path d="M0,14 30,14" stroke="#000" stroke-width="5" />
<path d="M0,23 30,23" stroke="#000" stroke-width="5" />
</svg>
</a>
</span>
</div>
</nav>
<div id="side-menu" class="side-nav">
×
<?php get_sidebar() ?>
</div>
<script type="text/javascript">
jQuery(document).ready(function(){
function openSlideMenu() {
document.getElementById('side-menu').style.width = '250px';
}
function closeSlideMenu() {
document.getElementById('side-menu').style.width = '0';
}
});
</script>
CSS
.side-nav {
height: 100%;
width: 0;
position: fixed;
z-index: 1;
top:0;
left:0;
background-color: #111;
opacity: 0.9;
overflow-x: hidden;
padding-top: 60px;
transition: 0.5s;
}
.side-nav a {
padding: 10px 10px 10px 30px;
text-decoration: none;
font-size:22px;
color: #ccc;
display: block;
transition: 0.3s;
}
.side-nav a:hover {
color: #fff;
}
.side-nav .btn-close {
position: absolute;
top: 0;
right: 22px;
font-size: 36px;
margin-left: 50px;
}
The tutorial seemed easy and simple, it should have worked without issues. I wonder could it be something WordPress related? I did all I could.
Since you are using jQuery, why don't you utilize it completely?
For more information on what could be the issue, I suggest you take a look at MarsAndBlack's comment
Meanwhile, I made some changes to your code to make use of jQuery fully.
Here I have added ids to both buttons. (Not necessary, but used for easy detection).
<nav class="navbar">
<div class="side-menu">
<span class="open-slide">
<a href="#" id="openmenu">
<svg width="30" height="30">
<path d="M0,5 30,5" stroke="#000" stroke-width="5" />
<path d="M0,14 30,14" stroke="#000" stroke-width="5" />
<path d="M0,23 30,23" stroke="#000" stroke-width="5" />
</svg>
</a>
</span>
</div>
</nav>
<div id="side-menu" class="side-nav">
×
</div>
Also changed JS to use jQuery for click function instead of vanilla JS,
jQuery(document).ready(function(){
jQuery('#openmenu').click(function() {
jQuery('#side-menu').css('width','250px');
});
jQuery('#closemenu').click(function() {
jQuery('#side-menu').css('width','0px');
});
});
Here is a working example

JS draw an arrow pointing from one div to another

I have the following code:
<div id="parent">
<div class="child" id="air1">Medium 1</div>
<div class="child" id="glass">Medium 2</div>
<div class="child" id="air2">Medium 1</div>
</div>
<style>
#parent {
background: #999;
padding: 0px;
}
#glass {
background: #666;
}
.child {
background: #ccc;
height: 200px;
margin: 0px;
}
</style>
I want to draw an arrow from #air1 into #glass using an svg. I added the following code into the div to draw an example arrow:
<svg width="300" height="100">
<defs>
<marker id="arrow" markerWidth="13" markerHeight="13" refx="2" refy="6" orient="auto">
<path d="M2,2 L2,11 L10,6 L2,2" style="fill:red;" />
</marker>
</defs>
<path d="M30,150 L100,50"
style="stroke:red; stroke-width: 1.25px; fill: none;
marker-end: url(#arrow);"
/>
</svg>
I don't want the arrow pointed in a random direction though, I want it to point into #glass like this:
Also, how would I go about drawing a less steep arrow like this as well:
How can I do this?
You can achieve that by using positioning (inserting the svg into the first section and set it to position: absolute;) and adjusting the offset of the path element. To make the arrow pointing down, just use a negative value for the second value of the path description attribute.
For more information see w3schools about path.
#parent {
background: #999;
padding: 0px;
}
#glass {
background: #666;
}
.child {
background: #ccc;
height: 200px;
margin: 0px;
position: relative;
}
svg {
position: absolute;
left: 0;
}
<div id="parent">
<div class="child" id="air1">Medium 1
<svg width="400" height="200">
<defs>
<marker id="arrow" markerWidth="13" markerHeight="13" refx="2" refy="6" orient="auto">
<path d="M2,2 L2,11 L10,6 L2,2" style="fill:red;" />
</marker>
</defs>
<path d="M-600,-10 L300,195" style="stroke:red; stroke-width: 1.25px; fill: none; marker-end: url(#arrow);" />
</svg>
</div>
<div class="child" id="glass">Medium 2</div>
<div class="child" id="air2">Medium 1</div>
</div>

stroke-dasharray to visual data without libraries

I am trying to animate stroke-dasharray of a svg circle based on data values without using libraries.
Data is coming from a javascript calculation, so length of stroke will be different from circle to another.
code will as following: Codepen
or
var circle_1 = 20,
circle_2 = 33,
circle_3 = 42;
document.getElementById('circle_1').innerHTML = circle_1;
document.getElementById('circle_2').innerHTML = circle_2;
document.getElementById('circle_3').innerHTML = circle_3;
.container {
text-align: center;
height: 200px;
}
li {
list-style: none;
display: inline-block;
margin: 100px 50px;
position: relative;
width: 100px;
height: 100px;
}
circle {
stroke: #222;
fill: transparent;
stroke-width: 3px
}
.result {
position: absolute;
top: 40%;
left: 40%;
}
<div class="container">
<li>
<svg width="100" height="100">
<circle cy="50" cx="50" r="40" stroke-dasharray="0em" stroke-dashoffset="0" />
</svg>
<div class="result" id="circle_1"></div>
</li>
<li>
<svg width="100" height="100">
<circle cy="50" cx="50" r="40" stroke-dasharray="0em" stroke-dashoffset="0" />
</svg>
<div class="result" id="circle_2"></div>
</li>
<li>
<svg width="100" height="100">
<circle cy="50" cx="50" r="40" stroke-dasharray="0em" stroke-dashoffset="0" />
</svg>
<div class="result" id="circle_3"></div>
</li>
</div>
If I understand you correctly, you want a pie chart using SVG circle and no library. I worked on something like that recently, here is a mixin I made:
http://codepen.io/Draccoz/pen/GJVJVM
=pie-chart($size, $ring-size, $ring-color: false, $bg-size: 0, $bg-color: transparent)
$d: $size - $ring-size
width: $size
height: $size
>
circle
cx: $size / 2
cy: $size / 2
&:nth-child(1)
r: $bg-size / 2
#if $bg-color
fill: $bg-color
&:nth-child(2)
font-size: $d * 1.01 * $PI
stroke-width: $ring-size
r: $d / 2
fill: transparent
#if $ring-color
stroke: $ring-color
/* stroke-linecap: round */
transition: stroke-dashoffset 1s ease-in-out
transform: translateY($size) rotate(-90deg)
stroke-dasharray: 1em 1em
stroke-dashoffset: 0
#content
Hope it helps.

Categories

Resources