Positioning an absolute element above other elements - javascript

So I am building this frontendmentor site and im having trouble positioning the shopping cart div on top of the rest of the elements. At first i tried using z-index but apparently that doesnt work with elements that have a position style. I used position relative on the parent and absolute on the child so it would always appear under the shopping cart icon. Is there any other way to force an element on top or should i change the way i position the div.
.right-container {
padding: 1rem;
}
.account-container {
display: flex;
align-items: center;
position: relative;
}
.cart-icon-container {
margin-right: 2rem;
}
.cart-icon-container img {
height: 30px;
width: 30px;
aspect-ratio: 1;
}
.shopping-cart-overlay {
position: absolute;
top: 5rem;
right: 100px;
width: 400px;
border-radius: 10px;
box-shadow: 0 1rem 10px rgba(0, 0, 0, 0.185);
}
.shopping-cart-content {
display: flex;
justify-content: center;
align-items: center;
padding: 2rem 1rem;
}
<div class="right-container">
<div class="account-container">
<div class="shopping-cart-overlay">
<div class="shopping-cart-header">
<h4>Cart</h4>
</div>
<div class="shopping-cart-content">
<p>Your cart is empty</p>
</div>
</div>
<a href="/index.html" class="cart-icon-container">
<img src="./images/icon-cart.svg" alt="cart">
</a>
<img class="avatar" src="./images/image-avatar.png" alt="profile-pic">
</div>
</div>

Well it does work. Read this to get a better understanding of how z-index works with position. You just couldn't notice it because the div was transparent.
Check out the snippet below. It's your exact code, but I changed the background and positioned the .shopping-cart-overlay element closer to the other elements, just to show you that it actually works.
.right-container {
padding: 1rem;
}
.account-container {
display: flex;
align-items: center;
position: relative;
}
.cart-icon-container {
margin-right: 2rem;
}
.cart-icon-container img {
height: 30px;
width: 30px;
aspect-ratio: 1;
}
.shopping-cart-overlay {
position: absolute;
//top: 5rem;
//right: 100px;
width: 400px;
border-radius: 10px;
box-shadow: 0 1rem 10px rgba(0, 0, 0, 0.185);
/* Changes */
top: 0;
left: 125px;
z-index: 99;
background-color: red;
}
.shopping-cart-content {
display: flex;
justify-content: center;
align-items: center;
padding: 2rem 1rem;
}
<div class="right-container">
<div class="account-container">
<div class="shopping-cart-overlay">
<div class="shopping-cart-header">
<h4>Cart</h4>
</div>
<div class="shopping-cart-content">
<p>Your cart is empty</p>
</div>
</div>
<a href="/index.html" class="cart-icon-container">
<img src="./images/icon-cart.svg" alt="cart">
</a>
<img class="avatar" src="./images/image-avatar.png" alt="profile-pic">
</div>
</div>

Related

height: 0; overflow: hidden; not working with padding

I have this piece of code, my goal is to make custom select with smooth animation.
I've chosen to make my height by default 0 with overflow: hidden, and set height to auto when .active is added. But ran into problem that body is still shown. Problem seems to be with paddings
.select-header {
display: flex;
justify-content: space-between;
align-items: center;
height: 50px;
padding: 0 35px 0 20px;
background-color: #D6E7D2;
cursor: pointer;
transition: background 0.5s;
}
.select-body {
height: 0;
overflow: hidden;
padding-top: 27px;
padding-left: 20px;
padding-bottom: 31px;
background-color: #DCE9D9;
transition: all 0.5s;
}
.select.active .select-body {
height: auto;
}
.select-item {
line-height: 35px;
cursor: pointer;
color: #499A18;
}
.select-item:not(:last-child) {
padding-bottom: 12px;
}
<div class="select accordion">
<div class="select-header">
<span class="select-current">City</span>
<div class="select-icon"></div>
</div>
<div class="select-body">
<div class="select-item">Canandaigua, NY</div>
<div class="select-item">New York City</div>
<div class="select-item">Yonkers, NY</div>
<div class="select-item">Sherrill, NY</div>
</div>
</div>
I've tried putting body in container - didn't work. And to add padding when .active is added - this causes unexpected transition behavior.
The real problem here is that you cannot animate from height: 0; (size value) to height: auto; (keyword value), they must both be size values. You would need to know the exact expanded height. What you can do is animate the max-height from 0 to some really big size that should always be larger than the contents; in my example I use 200vh (twice the viewport height).
Also, just apply and remove the padding the same as you do with height.
const toggle = document.querySelector('.select-header')
toggle.addEventListener('click', () => toggle.parentElement.classList.toggle('active'))
.select-header {
display: flex;
justify-content: space-between;
align-items: center;
height: 50px;
padding: 0 35px 0 20px;
background-color: #D6E7D2;
cursor: pointer;
transition: background 0.5s;
}
.select-body {
height: auto;
max-height: 0;
overflow: hidden;
padding-top: 0;
padding-left: 20px;
padding-bottom: 0;
background-color: #DCE9D9;
transition: all 0.5s;
}
.select.active .select-body {
max-height: 200vh;
padding-top: 27px;
padding-bottom: 31px;
}
.select-item {
line-height: 35px;
cursor: pointer;
color: #499A18;
}
.select-item:not(:last-child) {
padding-bottom: 12px;
}
<div class="select accordion">
<div class="select-header">
<span class="select-current">City</span>
<div class="select-icon"></div>
</div>
<div class="select-body">
<div class="select-item">Canandaigua, NY</div>
<div class="select-item">New York City</div>
<div class="select-item">Yonkers, NY</div>
<div class="select-item">Sherrill, NY</div>
</div>
</div>

Why does my page width only stretch to 100% with "fit-content"?

I have tried looking around for this but can't seem to find a question to match my current problem. I am trying to build a mock ecommerce website to practice using React. I have a header component. I want this component to be 100% of the screen width, so that the elements inside this component shrink whenever the page shrinks. I have some global css that sets the height and width of the html and body to 100%:
html, body{
background-color: rgb(167, 72, 72);
height: 100%;
min-width: 100%;
}
I am currently facing two problems, neither of which I understand very well the causes of. When I set my header component (the outermost component) to have a width of 100%, the page shrinks correctly. But when I open up developer tools to check the responsiveness, something goes wrong so that the right side of my header is shrinking faster than the page header_shrink
I am able to fix this by setting the width of my header to "fit-content" instead of "100%". Here is what the header looks like when I shrink the page using developer tools.header_fixed But when I do it this way, the components inside of my header don't shrink correctly. For example, my search bar is supposed to decrease in width as I shrink the page, but when I use "fit-content", it just stays set to whatever size it is. search-bar-constant. When I have the width set to 100% instead of fit content, it looks the way it's supposed to search-bar-fixed.
Sorry for the long explanation, but this is the bulk of my problem. "Width: 100%" allows the items in my header component to shrink correctly, but not the component itself. And "width: fit-content" allows the outer header component to shrink correctly, but not the items inside of it.
Here is the JSX I have for reference:
import React from 'react'
import './Header.css'
import { BiSearchAlt2 as SearchIcon} from "react-icons/bi";
import {RiArrowDropDownLine as DropDownIcon} from "react-icons/ri";
import { CgProfile as Profile } from "react-icons/cg";
import { CgShoppingCart as Cart } from "react-icons/cg";
const Header = () => {
const texts = [
'ORDERS OF $5K SHIP FREE',
'FREE SHIPPING ON SELECT ITEMS: SHOP NOW',
'BUY A RIG AND YOUR ENTIRE ORDER SHIPS FREE'
];
let currentTextIndex = 0;
setInterval(() => {
const shippingDealsText = document.querySelector('.shipping-deals-text');
shippingDealsText.classList.add('out');
setTimeout(() => {
shippingDealsText.textContent = texts[currentTextIndex];
shippingDealsText.classList.remove('out');
currentTextIndex = (currentTextIndex + 1) % texts.length;
}, 1000);
}, 5000);
return (
<div className="header">
<div className="header-top">
<div className="top-logo">
<h5 className='small-logo'>LEVIATHAN</h5>
</div>
<div className="space"></div>
<div className="link-container">
<div className="link-wrap">
Gift Cards
</div>
<div className="link-wrap">
Contact Us
</div>
<div className="link-wrap">
Order Status
</div>
<div className="link-wrap">
Live Chat
</div>
</div>
</div>
<div className="header-middle">
<div className="middle-logo">
<h5 className='big-logo'>LEVIATHAN</h5>
</div>
<div className="search-container">
<div className="search-wrapper">
<input
type="text"
id="search-bar"
placeholder="Search"
className='search'
/>
<div className="search-icon-wrapper">
<SearchIcon className='search-icon'/>
</div>
</div>
</div>
<div className="shipping-deals-container">
<div className="button-container">
<div className="shipping-deals-button">
<span className="deals-text">DAILY SHIPPING DEALS </span>
</div>
</div>
<div className="text-container">
<div className="text-slideshow">
<p className="shipping-deals-text">BUY A RIG AND YOUR ENTIRE ORDER SHIPS FREE</p>
</div>
</div>
</div>
<div className="icons-right">
<Profile className='login-pic'/>
<span>Log In</span>
<Cart className='shopping-cart'/>
</div>
</div>
<div className="header-bottom">
<div className="nav-bar">
<ul className='navigation'>
<li className='menu-items'>
<a href="/" className='button drop-down red'>Shop <DropDownIcon className='drop-icon'/></a>
<a href="/" className='button'>Equipment for Crossfit</a>
<a href="/" className='button'>New Gear</a>
<a href="/" className='button'>Barbells</a>
<a href="/" className='button'>Plates</a>
<a href="/" className='button'>Rigs and Racks</a>
<a href="/" className='button'>Shoes</a>
<a href="/" className='button'>Apparel</a>
<a href="/" className='button'>3 Ships Free</a>
<a href="/" className='button'>Zeus</a>
<a href="/" className='button drop-down'>The Index</a>
</li>
</ul>
</div>
</div>
</div>
)
}
export default Header
Here is the styling I am currently applying:
.header {
min-width: 100%;
margin: 0;
padding: 0;
}
.header-top {
background-color: white;
display: flex;
height: 2.5rem;
width: 100%;
}
.top-logo {
position: relative;
margin-left: 3rem;
}
.space {
flex-grow: 1;
}
.small-logo {
padding-top: 0.5em;
position: relative;
font-size: larger;
color: rgb(133, 133, 133)
}
.link-container {
display: flex;
/*border: 1px solid red;*/
margin-right: 3rem;
}
.link-wrap {
/*border: 1px solid green;*/
font-size: 14px;
padding-left: 1rem;
padding-top: 0.75rem;
}
.link-wrap a {
text-decoration: none;
color:#666666;
cursor: pointer;
}
/* Large section of header, black background */
.header-middle {
background-color: black;
height: 7rem;
display: flex;
}
/* Big LEVIATHAN text */
.middle-logo {
/*border: 1px solid red;*/
position: relative;
margin-left: 3rem;
display: flex;
justify-content: center;
align-items: center;
cursor: co;
}
.big-logo {
font-size: 48px;
/*padding-top: 2rem;*/
position: relative;
color: white;
}
.big-logo:hover {
color: rgb(210, 0, 0);
}
.search-container {
position: relative;
width: 40%;
display: flex;
flex-basis: 60%;
margin-left: 3rem;
align-items: center;
justify-content: center;
}
/*This is what has the appearance of the search bar*/
.search-wrapper {
min-width:100%;
height: 35%;
position: relative;
background-color: white;
display: flex;
flex-basis: 50%;
}
.search-icon-wrapper {
display: flex;
justify-content: center;
align-items: center;
width: 3rem;
}
.search-icon {
color: black;
font-size: 20px;
}
/*This is the actual search bar tucked inside*/
.search {
width: 100%;
height: 100%;
border: none;
outline: none;
margin-left: 1em;
font-size: 17px;
}
.search::placeholder {
color:rgb(94, 94, 94);
}
/* This holds onto both our daily shipping deals button */
/* and our text slideshow */
.shipping-deals-container{
width: 18em;
margin-left: 2.5em;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
/*border: 2px solid rgb(136, 77, 255);*/
}
.shipping-deals-button {
width: 65%;
height: 44%;
background-color: rgb(234, 2, 2);
position: relative;
display: flex;
justify-content: center;
align-items: center;
margin-top: 1.5em;
}
.button-container {
width: 100%;
height: 50%;
/*border: 2px solid magenta;*/
}
.deals-text {
color: white;
font-size: 12px;
position: relative;
text-align: center;
align-items: stretch;
width: 100%;
}
.text-container {
/*border: 2px solid rgb(20, 182, 11);*/
width: 100%;
height: 50%;
}
.text-slideshow {
color: white;
width: 100%;
height: 50%;
font-size: 12px;
}
.shipping-deals-text {
transition: opacity 1s;
opacity: 1;
font-size: 13px;
}
.out {
opacity: 0;
transition: opacity 1s;
}
.shipping-deals-text-red{
color: red;
}
.navigation {
display: flex;
align-items:flex-start;
height: 3rem;
}
.menu-items {
height: 100%;
margin-left: 1.5rem;
padding-right: 1.5rem;
display: flex;
align-items: flex-start;
flex: 1;
}
ul {
list-style-type: none;
background-color: #333333;
}
.button {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
height: 100%;
text-decoration: none;
color: white;
text-transform: uppercase;
white-space: nowrap;
padding: 1em;
font-weight: bold;
}
.button:hover {
color:rgb(210, 0, 0)
}
.red {
background-color: rgb(210, 0, 0);
}
.red:hover {
color: white;
}
.drop-icon {
font-size: 25px;
}
.icons-right {
height: 50%;
margin-top: 2em;
min-width: 10%;
display: flex;
justify-content: center;
align-items: center;
margin-right: 1rem;
}
.login-pic {
color: white;
font-size: 20px;
}
.shopping-cart {
color: white;
font-size: 20px;
margin-left: 1rem;
}
.icons-right span {
color: white;
margin-left: 0.5em;
}
#media (max-width: 1025px) {
.shipping-deals-container {
display: none;
}
.header-top {
display: none;
}
.header-middle {
height: 50%;
}
.search-wrapper {
border: 2px solid white;
height: 2rem;
}
.icons-right {
margin-bottom: 2rem;
}
}
I have tried altering the width of my body, and html, but nothing seems to be giving me the solution I am looking for
With width: 100% on .header it shrinks the header the way you want it. That seems to be correct actually.
The element that prevents shrinking is <li class="menu-items"></li> because of display: flex;. Flexbox is by default not wrapping (flex-wrap: nowrap;).
Add flex-wrap. wrap; and you'll see everything will shrink with fit-content or width: 100%;
Hope this helps.
On another note: You shouldn't use <li> (List-Element) as the list. Thats what <ul> (Unsorted list) is for.
It should look more like this ->
<ul>
<li>
Shop
</li>
<li>
Equipment for Crossfit
</li>
<li>
New Gear
</li>
<!-- ... -->
</ul>

All the elements disappear when I click on one of them, but only need the elements that I haven't clicked on to disappear

I want all the other elements(that I haven't clicked on) to disappear when I click on one of them, but instead all of them disappear. Here's the Javascript Code:
$(".content-toggler").click(function() {
let elTriggered = $(this);
elTriggered.parent().toggleClass("expand");
$(".content-toggler").each(function(index, element) {
if ($(element) === elTriggered) {
console.log("Passing on the clicked element...");
} else {
$(element).parent().toggleClass("hide");
}
console.log($(element))
console.log(elTriggered)
});
});
.circular-anim {
display: grid;
align-items: center;
justify-content: center;
margin: 1em auto;
/*With 'auto', you center the element according to the margin*/
margin-top: 0;
padding: 0;
width: 100%;
height: 100%;
border-radius: 2em;
position: absolute;
background: rgba(0, 0, 0, 0.25);
transition: 1s ease;
}
.content-toggler {
margin: 0;
padding: 0;
border-style: none;
background: #8D9CF4;
width: 175px;
height: 175px;
border-radius: 50%;
position: absolute;
top: 32.5px;
left: 188.5px;
}
.hide {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="page-content">
<div class="circular-anim"><button class="content-toggler"></button></div>
<div class="circular-anim"><button class="content-toggler"></button></div>
<div class="circular-anim"><button class="content-toggler"></button></div>
<div class="circular-anim"><button class="content-toggler"></button></div>
</div>
By the way, I injected some of the content from the js file and they already work well. Don't be surprised if you see some of the classes missing in the css code.
Why do all my elements disappear even though I want the one that I click on to stay?
Each time you call $() it creates a new jQuery object, and it will not compare equal to another object even if they refer to the same DOM element.
You can just use the .not() function to remove an element from the collection, instead of looping with .each() and comparing.
$(".content-toggler").click(function() {
let elTriggered = $(this);
elTriggered.parent().toggleClass("expand");
$(".content-toggler").not(this).toggleClass("hide");
});
.circular-anim {
display: grid;
align-items: center;
justify-content: center;
margin: 1em auto;
/*With 'auto', you center the element according to the margin*/
margin-top: 0;
padding: 0;
width: 100%;
height: 100%;
border-radius: 2em;
position: absolute;
background: rgba(0, 0, 0, 0.25);
transition: 1s ease;
}
.content-toggler {
margin: 0;
padding: 0;
border-style: none;
background: #8D9CF4;
width: 175px;
height: 175px;
border-radius: 50%;
position: absolute;
top: 32.5px;
left: 188.5px;
}
.hide {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="page-content">
<div class="circular-anim"><button class="content-toggler"></button></div>
<div class="circular-anim"><button class="content-toggler"></button></div>
<div class="circular-anim"><button class="content-toggler"></button></div>
<div class="circular-anim"><button class="content-toggler"></button></div>
</div>

Remove instance of inner element only when specific parent is clicked

I have a series of elements where I'd like it when one of the boxes is clicked the inner box on that specific element disappears. I've been playing around with it but can't get it work. I'm wondering if I should be using this in the code?
In the example below I want it so when you click one of the red boxes, that particular box's inner yellow box disappears, but only the yellow box inside the red box that is clicked.
I need to do it with without adding any more classes or IDs to the HTML.
CodePen: https://codepen.io/emilychews/pen/dyNPwEx
var boxOuter = document.querySelectorAll(".box-outer"),
boxInner = document.querySelectorAll(".box-inner");
if (boxOuter) {
boxOuter.forEach(function (item) {
item.addEventListener("click", function () {
// code goes here
});
});
}
body {
margin: 0;
display: flex;
justify-content: center;
align-items: center;
height: 120vh;
}
.box-outer {
position: relative;
width: 10rem;
height: 5rem;
background: red;
margin: 1rem;
cursor: pointer;
}
.box-inner {
width: 1rem;
height: 1rem;
background: yellow;
position: absolute;
bottom: 0.5rem;
right: 0.5rem;
}
<main class="main-wrapper">
<div class="box-outer">
<div class="box-inner"></div>
</div>
<div class="box-outer">
<div class="box-inner"></div>
</div>
<div class="box-outer">
<div class="box-inner"></div>
</div>
</main>
This should do the job
var boxOuter = document.querySelectorAll(".box-outer"),
boxInner = document.querySelectorAll(".box-inner");
if (boxOuter) {
boxOuter.forEach(function (item) {
item.addEventListener("click", function () {
//This will delete everything inside the box... Clear all child nodes
this.innerHTML = '';
//Hide inner child
//this.children[0].style.visibility = 'hidden';
// code goes here
});
});
}
body {
margin: 0;
display: flex;
justify-content: center;
align-items: center;
height: 120vh;
}
.box-outer {
position: relative;
width: 10rem;
height: 5rem;
background: red;
margin: 1rem;
cursor: pointer;
}
.box-inner {
width: 1rem;
height: 1rem;
background: yellow;
position: absolute;
bottom: 0.5rem;
right: 0.5rem;
}
<main class="main-wrapper">
<div class="box-outer">
<div class="box-inner"></div>
</div>
<div class="box-outer">
<div class="box-inner"></div>
</div>
<div class="box-outer">
<div class="box-inner"></div>
</div>
</main>
Instead of selecting the inner element globally, you could make this inside the listener. And then use the setAttribute method to change the display property to 'none'.
var boxOuter = document.querySelectorAll(".box-outer");
if (boxOuter) {
boxOuter.forEach(function (item) {
item.addEventListener("click", function () {
const boxInner = item.querySelector(".box-inner"); // captures the respective box
boxInner.setAttribute("style", "display: none;"); // sets the display attribute
});
});
}
body {
margin: 0;
display: flex;
justify-content: center;
align-items: center;
height: 120vh;
}
.box-outer {
position: relative;
width: 10rem;
height: 5rem;
background: red;
margin: 1rem;
cursor: pointer;
}
.box-inner {
width: 1rem;
height: 1rem;
background: yellow;
position: absolute;
bottom: 0.5rem;
right: 0.5rem;
}
<main class="main-wrapper">
<div class="box-outer">
<div class="box-inner"></div>
</div>
<div class="box-outer">
<div class="box-inner"></div>
</div>
<div class="box-outer">
<div class="box-inner"></div>
</div>
</main>

How to overlap images using flexbox while maintaing it's ability responsive design

click here to see my code
The goal here is to perfectly overlap the images.
The eyes (blue ovals) should display on the face (peach circle). I'm using chrome as my browser. But hope it will display the same on any browser used.
Like so (minus the nose):
What I tried:
changing the position of the images from relative to absolute (With one image set as absolute I should have been able to move it anywhere I wanted on the page.)
setting align-self: flex-start (Sometimes browsers have weird default setting. I was told this might override a chrome default that was stopping me from moving the image.)
setting align-self: center (This was also an attempt to override a chrome default)
I can't figure out how to overlap the two images let alone add any code to my CSS file that will move the images.
function setDefaultImage(){
var defaultImage = document.getElementById(img_face).src = "https://drive.google.com/file/d/1_seSuUcgJgd5qQTUcreDuYo_zfVpRzsa/view?usp=sharing";
}
.flex-container {
display: flex;
background-color: darkred;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
}
.flex-container > div {
background-color: black;
margin: 1%;
padding: 5%;
width:38%;
}
img{
align-self: flex-start;
text-align: center;
width: 100%;
}
.img_face{
position: absolute;
top: 0;
z-index: 1;
}
.img_eyes{
position: absolute;
top: 0;
z-index: 2;
}
<!DOCTYPE html>
<html>
<body>
<div class="flex-container">
<div id = "left">
<button type="reset" id="reset" class="button" onclick = setDefaultImage()>Reset</button>
</div>
<div id = "right">
<img id="img_face" src="white_face.png" alt="White Face" >
<img id="img_eyes" src="blue_eyes.png" alt="Blue Eyes" >
</div>
</div>
Here's a couple different approaches with room for tinkering to help your learning. Happy Holidays!
hiUser = (val) => {
const box1 = document.getElementById('box1'),
box2 = document.getElementById('box2'),
blah = `${val}px`;
box1.style.height = blah;
box1.style.width = blah;
box2.style.height = blah;
box2.style.width = blah;
}
div {
display: flex;
align-items: center;
/* default initial values */
height: 100px;
width: 100px;
margin-top: 2rem;
}
span {
background-color: blue;
height: 20%;
width: 10%;
border-radius: 50%;
margin-bottom: 30%;
}
figure, #box1 {
position: relative;
background-color: wheat;
border-radius: 50%;
margin: 0;
}
figure {
height: 100%;
width: 100%;
}
#box1 {
justify-content: space-around;
}
#box1 span {
margin-right: 20%;
}
#box1 span:first-child {
margin-left: 20%;
margin-right: 0;
}
figure:before, figure:after {
content: '';
display: block;
position: absolute;
top: 25%;
background-color: blue;
height: 20%;
width: 10%;
border-radius: 50%;
}
figure:before {
left: 30%;
}
figure:after {
right: 30%;
}
label {
display: block;
margin: 2rem 0 1rem 0;
}
Slide to change size:
<input type="range"
name="fu"
min="0"
max="500"
onchange="hiUser(this.value)"
oninput="hiUser(this.value)">
<label>Flex;</label>
<div id="box1">
<span></span>
<span></span>
</div>
<label>Pseudo;</label>
<div id="box2">
<figure></figure>
</div>

Categories

Resources