I have a parent <div /> that covers the whole page. Within this parent <div /> I am having a smaller child <div />. I do not want the child <div /> to be clickable, when the parent <div /> overlays the child `.
function parentFunction(event) {
if (document.getElementById("check").checked) {
event.stopPropagation();
}
}
function childFunction() {
alert("CHILD");
}
.child {
padding: 50px;
width: 100px;
height: 100px;
background-color: hotpink;
text-align: center;
cursor: pointer;
}
.parent {
width: 500px;
height: 500px;
filter: blur(2px);
display: flex;
justifc-content: center;
align-items: center;
align-content: center;
background-color: lightgray;
}
<body>
<div
onclick="parentFunction(event)"
class="parent">
<div
onclick="childFunction()"
class="child">
Child
</div>
</div>
</body>
Stop propagation:
<input type="checkbox" id="check">
Here's a solution that would likely answer your need.
When you click on the Parent, which holds a child inside, it will tell you which element was clicked. Then you can if yourself into the destination/solution you require in the functionality.
document.querySelector(".parent").addEventListener("click", parentFunction)
function parentFunction(e) {
if (document.getElementById("check").checked && e.target == document.querySelector(".child")) {
e.stopPropagation();
console.log("EXIT")
return;
}
console.log("PARENT says target is: ", e.target)
}
body {
display: flex;
justifc-content: center;
align-items: center;
flex: 1;
width: 100vh;
height: 100vw;
}
.child {
padding: 50px;
width: 100px;
height: 100px;
background-color: hotpink;
text-align: center;
cursor: pointer;
}
.parent {
width: 500px;
height: 500px;
filter: blur(2px);
display: flex;
justify-content: center;
align-items: center;
align-content: center;
background-color: lightgray;
cursor:pointer;
}
<body>
<div
class="parent">
<div
class="child">
Child
</div>
</div>
</body>
Stop propagation:
<input type="checkbox" id="check">
As it was previously stated the propagation goes from child to parent and not the other way around.
Possibilities you have:
add the style pointer-events: none to the child div
or
in the childFunction() check if the parent div exists and if so just return;
It is on the other way around, when you click on the child you don't want the event to be propagated to the parent which is overlapping it, so it should be instead:
function parentFunction(event) {
console.log("PARENT");
}
function childFunction() {
if (document.getElementById("check").checked) {
event.stopPropagation();
}
console.log("CHILD");
}
.child {
padding: 50px;
width: 100px;
height: 100px;
background-color: hotpink;
text-align: center;
cursor: pointer;
}
.parent {
width: 500px;
height: 500px;
filter: blur(2px);
display: flex;
justify-content: center;
align-items: center;
align-content: center;
background-color: lightgray;
}
<body>
<div onclick="parentFunction(event)" class="parent">
<div onclick="childFunction()" class="child">
Child
</div>
</div>
</body>
Stop propagation:
<input type="checkbox" id="check">
Related
I have a simple section that contains five elements on default the first element background is red (active element) now I want when u click any of the remaining elements to change the background color to red, and the remaining elements to have white background color using vanilla js.
Problem: When I click any of the remaining elements is set to red but the previous active element is still red; live demo
My solution
HTML
<div id="panels">
<div class="panel active">First</div>
<div class="panel">second</div>
<div class="panel">third</div>
<div class="panel">fouth</div>
<div class="panel">Fith</div>
</div>
CSS
#panels{
display: flex;
justify: space-between;
align-items: center
}
.panel{
display: flex;
justify-content: space-between;
align-items: center;
width: 100px;
height: 100px;
background: white;
color: black;
font-size: 24px;
text-align: center;
margin: 0px auto;
cursor: pointer;
}
.active{
background: red;
}
Js
var panel = document.getElementById('panels'); // Parent
panel.addEventListener('click', function (e) {
var target = e.target; // Clicked element
while (target && target.parentNode !== panel) {
target = target.parentNode; // If the clicked element isn't a direct child
if (!target) { return; } // If element doesn't exist
}
if (target.tagName === 'DIV') {
target.classList.toggle('active');
} else {
console.log('love')
}
});
What do I need to change here to get this working?
var panels = document.querySelectorAll("#panels > .panel")
panels.forEach(each=>{
each.onclick = function(){
panels.forEach(ss=>ss.classList.remove("active")) // removing active from all
each.classList.add("active") // assigning active to selected
}
})
.panel{
display: flex;
justify-content: space-between;
align-items: center;
width: 100px;
height: 100px;
background: white;
color: black;
font-size: 24px;
text-align: center;
margin: 0px auto;
cursor: pointer;
}
.active{
background: red;
}
<div id="panels">
<div class="panel active">First</div>
<div class="panel">second</div>
<div class="panel">third</div>
<div class="panel">fouth</div>
<div class="panel">Fith</div>
</div>
Just for fun and educational purposes, here's a solution with no JavaScript. Just hidden HTML radio buttons and a CSS trick.
#panels {
display: flex;
justify: space-between;
align-items: center
}
.panel {
display: flex;
justify-content: center;
align-items: center;
width: 100px;
height: 100px;
background: white;
color: black;
font-size: 24px;
text-align: center;
margin: 0px auto;
cursor: pointer;
}
[type=radio]:checked + .panel {
background: red;
}
[type=radio] {
display: none;
}
<div id="panels">
<input type="radio" name="panel" id="panel1" checked />
<label class="panel" for="panel1">First</label>
<input type="radio" name="panel" id="panel2" />
<label class="panel" for="panel2">second</label>
<input type="radio" name="panel" id="panel3" />
<label class="panel" for="panel3">third</label>
<input type="radio" name="panel" id="panel4" />
<label class="panel" for="panel4">fouth</label>
<input type="radio" name="panel" id="panel5" />
<label class="panel" for="panel5">Fith</label>
</div>
A modern (not supported in IE) take on panels.
Vanilla JavaScript supported in all browsers.
The Custom Element <div-panels> process the click Event
customElements.define("div-panels", class extends HTMLElement{
connectedCallback(){
this.onclick = (evt) => {
this.querySelector("[selected]")?.removeAttribute("selected");
evt.target.setAttribute("selected","selected");
}
}
});
div-panels > div {
display: inline-block;
width: 100px;
height: 100px;
background: pink;
}
div-panels > div[selected] {
background: green;
}
<div-panels>
<div>First</div>
<div>Second</div>
<div selected>Third</div>
<div>Fourth</div>
<div>Fith</div>
</div-panels>
const Elements = document.querySelectorAll(".panel");
Elements.forEach((el) => {
el.onclick = () => {
if (el.classList.contains("active")) {
// if you want to remove the red
el.classList.remove("active");
} else {
let CurrentActive = document.querySelector(".active");
CurrentActive ?CurrentActive.classList.remove("active") :""
el.classList.add("active");
}
};
});
.panel{
display: flex;
justify-content: space-between;
align-items: center;
width: 100px;
height: 100px;
background: white;
color: black;
font-size: 24px;
text-align: center;
margin: 0px auto;
cursor: pointer;
}
.active{
background: red;
}
<div id="panels">
<div class="panel active">First</div>
<div class="panel">second</div>
<div class="panel">third</div>
<div class="panel">fouth</div>
<div class="panel">Fith</div>
</div>
I currently am trying to code a website to animate moving across the x-axis to access different sections of the page (page content in 'tab-content'). I have a navbar that has different headers, this is fixed, I want the user to click on each header and be taken to that section. I managed to take the user to the desired section/div with some JS code however, there isn't any animation it defaults to the selected section/div just suddenly being on screen. How do I animate with pure JS or CSS. I need the clicking of the header to move (motion) the user to that div. I'm new to web dev.
here some of my code
HTML
<div class="main-info">
<div class="nav-container">
<div class="nav-bar">
<ul>
<li data-tab-target="#show" class="tab">Show</li>
<li data-tab-target="#about" class="tab">About</li>
<li data-tab-target="#lookbook" class="tab">Lookbook</li>
<li data-tab-target="#process" class="tab">Process</li>
</ul>
</div>
<div class="info overlay">
<div class="text">
MA
Coming Soon
BA
</div>
Back
</div>
</div>
<div class="tab-content">
<div id="show" data-tab-content class="active">
<p>VIDEO</p>
</div>
<div id="about" data-tab-content>
<p>About</p>
</div>
<div id="lookbook" data-tab-content>
<p>Lookbook</p>
</div>
<div id="process" data-tab-content>
<p>Process</p>
</div>
</div>
</div>
CSS
.main-info {
background-color: transparent;
height: 100vh;
overflow: hidden;
}
.nav-container {
position: fixed;
}
.nav-bar {
width: 80vw;
height: 10vh;
left: 10vw;
position: absolute;
top: 5vh;
}
.nav-bar ul {
text-transform: uppercase;
list-style: none;
margin: 0;
padding: 0;
display: flex;
justify-content: space-around;
}
.tab a {
font-family: Helvetica, sans-serif;
font-weight: bold;
font-size: 1rem;
color: black;
text-decoration: none;
}
.tab:hover {
cursor: pointer;
opacity: 0.6;
}
.tab.active {
background-color: whitesmoke;
}
.info {
width: 90vw;
height: 10vh;
/* border: 1px solid red; */
left: 5vw;
position: absolute;
top: 80vh;
display: flex;
justify-content: space-between;
align-items: flex-end;
}
.info a {
font-family: Helvetica, sans-serif;
font-weight: bold;
font-size: 1.1rem;
color: black;
text-decoration: none;
border: 1px solid teal;
}
.text {
width: 30%;
display: flex;
justify-content: space-between;
}
.tab-content {
border: 1px solid teal;
position: absolute;
left: 0;
top: 0;
height: 100vh;
z-index: -11;
display: flex;
flex: row nowrap;
justify-content: flex-start;
}
[data-tab-content] {
border: 1px solid blueviolet;
background-color: violet;
font-size: 3rem;
color: blue;
scroll-behavior: smooth;
display: none;
width: 100vw;
height: 100vh;
}
.active[data-tab-content] {
display: block;
}
JS
const tabs = document.querySelectorAll('[data-tab-target]');
const tabContents = document.querySelectorAll('[data-tab-content]')
// loop through the list to find the one tab mouse clicked
tabs.forEach(tab => {
tab.addEventListener('click', () => {
const target = document.querySelector(tab.dataset.tabTarget)
tabContents.forEach(tabContent => {
tabContent.classList.remove('active')
})
tabs.forEach(tab => {
tab.classList.remove('active')
});
tab.classList.add('active')
target.classList.add('active');
});
});
You almost got it. Instead of setting the scroll-behavior on the elements that are inside a scrollable element, put it on either the element that has a scrollbar.
.tab-content {
scroll-behavior: smooth;
}
Or on the top most element to have all elements move with a smooth scrolling animation.
:root {
scroll-behavior: smooth;
}
I've got some text that is positioned center of the container and I would like to have some other text that starts where the text positioned in center starts (these divs are not having the same length so here is the problem) I tried by adding jquery to get the X position but no success, and I have no clue how to solve it only with css.
Here's my code:
<div class="graphic-icons-page">
<div class="container icons-container">
<div class="icons-software-title-left">Wide</div>
<div class="icons-software-title-center text-center"><span>Text in center</span></div>
</div>
</div>
.icons-container{
height:80vh;
background-color: black;
color:white;
}
.graphic-icons-page{
display: flex;
justify-content: center;
align-items: center}
///test
.icons-software-title-center{
width: 100%;
}
.icons-software-title-left{ font-size: 50px;}
.icons-software-title-center{
font-size:50px
}
Here's how I want to look:
I added one div and move the icons-container inside the other container. Would this work?
In this fiddle, I added bootstrap css to test https://jsfiddle.net/1aywg3Lm/
body {
background-color: black;
}
.container-center {
text-align: center;
}
.icons-container{
height:80vh;
background-color: black;
color:white;
display: inline-block;
text-align: left;
}
.graphic-icons-page{
display: flex;
justify-content: center;
align-items: center}
///test
.icons-software-title-center{
width: 100%;
}
.icons-software-title-left{ font-size: 20px;}
.icons-software-title-center{
font-size:20px
}
<div class="graphic-icons-page">
<div class="container">
<div class="icons-container">
<div class="icons-software-title-left">Wide</div>
<div class="icons-software-title-center text-center"><span>Text in center of the page</span></div>
</div>
</div>
</div>
I solved my issues using width:max-content
.container-center {
text-align: center;
width: 100%;
background-color: black;
}
.icons-container{
height:80vh;
background-color: black;
color:white;
display: inline-block;
text-align: left;
width: max-content;
}
I want to align some list elements that are created via Javascript with their corresponding buttons. Every time I add a new element to the list, the text appears in a lower position than the "X/Remove element" buttons. Can you please tell me what I'm doing wrong?
You can check the pen right here:
https://codepen.io/Watashi10/pen/RwwQegr
The ideal thing would be to have the list elements and the X buttons in the same line or at the same height under the "input" element.
Here is a screenshot of the actual list
HTML:
<body>
<div class="container d-flex align-items-center h-100">
<div class="row">
<header class="text-center col-12">
<h1 id="header">My Shopping List</h1>
</header>
<input class="text-center col-6" id="userinput" type="text" placeholder="add items">
<section class="row">
<button id="enter">Enter</button>
</section>
<div class="text-center col-12" id="shopping">
<ul class="list" style="list-style: none">
</ul>
</div>
</div>
</div>
<script type="text/javascript" src="script.js"></script>
</body>
CSS:
body,
html {
width: 100%;
height: 100%;
font-family: 'Fjalla One', sans-serif;
background: url("https://wallpaperplay.com/walls/full/5/6/5/68320.jpg") no-repeat center center fixed;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}
.container {
display: flex;
justify-content: center;
align-items: center;
align-content: center;
flex-wrap: wrap;
width: 15vw;
margin: 0 auto;
min-height: 50vh;
}
.row {
display: flex;
justify-content: center;
flex-direction: row;
}
#header {
display: inline-block;
position: relative;
bottom: 200px;
font-family: 'Fredericka the Great';
font-size: 5rem;
color: white;
}
input {
flex-grow: 5rem;
border: none;
padding: 25px;
}
button {
border: 1px solid;
background: blue;
color: white;
}
input, button {
position: relative;
bottom: 50px;
}
.userinput {
float: left;
}
h2 {
font-family: 'Fredericka the Great';
color:#FFB6C1;
font-size: 12px;
}
ul li {
padding: 3rem;
font-family: 'Fredericka the Great';
font-size: 25px;
color: #ffffff;
}
.done {
text-decoration: line-through;
}
I would appreciate any kind of help. Thank you!
Remove the bottom: 50px from
input, button {
position: relative;
bottom: 50px; //remove this
}
or if you want input to have bottom: 50px; seperate the css styling of them.
input {
position: relative;
bottom: 50px;
}
button {
position: relative;
margin-left: 15px !important; //just to make it a little nicer
}
So you're creating a textnode from the user input box here:
li.appendChild(document.createTextNode(input.value));
ul.appendChild(li);
input.value = "";
I would recommend making this a div or a p or something else that can be styled. Like so:
let inputValue = document.createElement('div');
inputValue.innerHTML = input.value;
li.prepend(inputValue)
input.value = "";
So you're li sctucture should look more like this:
<li>
<div class="value"></div>
<button></button>
</li>
After that, theres many ways to have these be inline. You could style the li to have a display: flex, or you could float the button to the right within the li. But I would start with making the value that you catch and put into the li something besides just the textNode.
I want 3 section one cover half part of the screen to show image slider and in half part, there is two section right now that part I'm done but now I want to add half part of the screen on top but it does not show image slider section, please help me.
right now my code:
<head runat="server">
<title></title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style>
body {
font-family: Arial;
color: white;
}
.split {
height: 100%;
width: 50%;
position: fixed;
z-index: 1;
top: 0;
overflow-x: hidden;
padding-top: 20px;
}
.left {
left: 0;
background-color: #ff6a00;
}
.right {
right: 0;
background-color: #ffd800;
}
.centered {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
text-align: center;
}
.centered img {
width: 150px;
border-radius: 50%;
}
</style>
</head>
<body>
<form id="form1" runat="server">
<div class="split left">
<div class="centered">
<h2>Blood Donor</h2>
<p>Go To Registration</p>
</div>
</div>
<div class="split right">
<div class="centered">
<h2>Blood Seeker</h2>
<p>Go To Registration</p>
</div>
</div>
</form>
</body>
please help me,
Thank You for your time.
He's a simple layout using CSS Grid (the 2D version of Flexbox):
.main {
display: inline-grid;
height: 200px;
width: 400px;
grid-template-rows: 50% 50%;
border: green solid 2px;
}
.main .level1 {
border: blue solid 2px;
display: flex;
}
.main .level1 .level2 {
border: red solid 2px;
flex-basis: 50%;
}
<div class="main">
<div class="level1"></div>
<div class="level1">
<div class="level2"></div>
<div class="level2"></div>
</div>
</div>
If you are happy using grid then is quite easy. You just need to setup a grid which with two columns and two rows.
Here is a link to a codepen, there are some other styles to make it a little easier to see what is going on but you only need to pay attention to the grid css attributes.
.container {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: repeat(2, 1fr);
height: 50vh;
}
.container>div {
display: flex;
justify-content: center;
align-items: center;
}
.image-slider {
background: magenta;
grid-column: span 2;
}
.page-link-1 {
background: red;
}
.page-link-2 {
background: green
}
<div class="container">
<div class="image-slider">Image Slider</div>
<div class="page-link-1">Page Link 1</div>
<div class="page-link-2">Page Link 2</div>
</div>
https://codepen.io/tmcnicol/pen/PdoLpm/
My implementation with flex:
body,
html {
height: 100%;
}
.wrap {
display: flex;
height: 100%;
flex-direction: column;
}
.slider {
border: 2px solid red;
flex: 1;
display: flex;
align-items: center;
justify-content: center;
}
.bottom-wrap {
display: flex;
flex: 1;
}
.link {
border: 2px solid red;
flex: 1;
display: flex;
align-items: center;
justify-content: center;
}
<div class="wrap">
<div class="slider">Image slider</div>
<div class="bottom-wrap">
<div class="link">Page Link</div>
<div class="link">Page Link</div>
</div>
</div>
Working codepen