Prevent shadow bleeding with position absolute element? - html

I'm developing a dropdown and I'm having an issue because I want to have an absolutely positioned container of items to appear when you hover over it, but the issue is that the shadow from this bleeds onto the actual dropdown itself. Here's a reproduction:
body {
display: flex;
flex-direction: column;
align-items: center;
margin-top: 50px;
}
.dropdown {
position: relative;
width: 200px;
height: 40px;
box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
background-color: #efefef;
}
.items {
display: none;
position: absolute;
overflow: hidden;
overflow-y: auto;
width: 100%;
height: 100px;
top: 100%;
box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
background-color: #f7f7f7;
}
.dropdown:hover .items {
display: block;
}
.item {
padding: 5px 10px;
}
<div class="dropdown">
<div class="items">
<div class="item">a</div>
<div class="item">b</div>
<div class="item">c</div>
<div class="item">d</div>
</div>
</div>
<div>hello</div>
As you can see, the top portion of the shadow from the .items container is visible when you mouse over the dropdown. Here's a picture of what I'm referring to:
The obvious solution is to just make the box shadow apply to only the dropdown, but then the issue is that since the items container is position absolute, it doesn't receive the box shadow.
Is there any way around this?

You could add a :before element on the .dropdown with a smaller height than he items. Like this:
.dropdown:hover:before {
position: absolute;
content: "";
width: 100%;
height: 98px;
box-shadow: rgb(0 0 0 / 24%) 0px 6px 8px;
background: red;
bottom: -100px;
z-index: 0;
}
Also, remove the shadow from the .items element.

I think Jackson has the right idea with using a pseudo element.
Although my approach would be the following:
.dropdown:hover::after {
content: '';
position: absolute;
width: 100%;
height: 100%;
background-color: #efefef;
}
body {
display: flex;
flex-direction: column;
align-items: center;
margin-top: 50px;
}
.dropdown {
position: relative;
width: 200px;
height: 40px;
box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
background-color: #efefef;
}
.items {
display: none;
position: absolute;
overflow: hidden;
overflow-y: auto;
width: 100%;
height: 100px;
top: 100%;
box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
background-color: #f7f7f7;
}
.dropdown:hover .items {
display: block;
}
.dropdown:hover::after {
content: '';
position: absolute;
width: 100%;
height: 100%;
background-color: #efefef;
}
.item {
padding: 5px 10px;
}
<div class="dropdown">
<div class="items">
<div class="item">a</div>
<div class="item">b</div>
<div class="item">c</div>
<div class="item">d</div>
</div>
</div>
<div>hello</div>
A second approach could be to grow the height of .dropdown on hover, and set the items list to a position not relative to .dropdown's height:
body {
display: flex;
flex-direction: column;
align-items: center;
margin-top: 50px;
}
.dropdown {
position: relative;
width: 200px;
height: 40px;
box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
background-color: #efefef;
}
.items {
display: none;
position: absolute;
overflow: hidden;
overflow-y: auto;
width: 100%;
height: 100px;
top: 40px;
box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
background-color: #f7f7f7;
}
.dropdown:hover .items {
display: block;
}
.dropdown:hover {
height: 140px;
}
.item {
padding: 5px 10px;
}
<div class="dropdown">
<div class="items">
<div class="item">a</div>
<div class="item">b</div>
<div class="item">c</div>
<div class="item">d</div>
</div>
</div>
<div>hello</div>

Related

Resizing div before parent

When I resize the page the searchbox starts resizing after the padding of the parent if zero. I want to resize the div with class-"searchbox", with resizing the page not after the parent's padding is off. Here is the code I'll be glad if you correct me anywhere.
.site-wrapper {
max-width: 86.5rem;
min-height: 28rem;
padding: 0 4.3rem;
margin: 0 auto;
overflow: hidden;
}
.navbar {
display: flex;
justify-content: end;
padding-top: 2.7rem;
}
#hamburger-button {
position: relative;
width: 32px;
height: 32px;
border-radius: 4px;
cursor: pointer;
}
#hamburger-button:hover {
background-color: #0000001f;
}
#hamburger {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border: none;
background-color: transparent;
background-image: url(/assets/menuicon.svg);
background-repeat: no-repeat;
background-size: contain;
padding: 9.2px;
margin: 0 auto;
cursor: pointer;
}
.header-content {
margin: 0 auto;
}
.header-content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.header-content-logo {
margin-top: 5rem;
margin-bottom: 2.3rem;
}
.header-content-logo svg {
width: 12.6rem;
}
.searchbox {
display: flex;
align-items: center;
border-radius: 6px;
width: 100%;
max-width: 38.7rem;
height: 2.7rem;
background-color: #fff;
box-shadow: 0px 2px 6px 1px rgba(0, 0, 0, 0.1);
overflow: hidden;
}
.searchbox:hover {
box-shadow: 0px 6px 20px 6px rgba(0, 0, 0, 0.1);
}
.searchbox input {
width: 92%;
border: none;
background-color: transparent;
font-size: 11.8pt;
font-family: inherit;
padding-left: 1rem;
}
.searchbox input:focus {
outline: none;
}
<div class="site-wrapper">
<div class="navbar">
<div id="hamburger-button">
<button id="hamburger"></button>
</div>
</div>
<div class="header-content">
<div class="header-content-logo">
<svg>
</div>
<div class="searchbox">
<input type="text" placeholder="Search without being tracked">
</div>
</div>
</div>
I have tried putting margin and even making another div before it and putting padding but seems that it didn't make it work. I am out of options.

Why doesn't my box-shadow overlap correctly on these flex children?

So basically the design of the page should look like this:
And when I try to implement through HTML and CSS:
as you can see here the Navbar's box shadow overlaps the header.
*{
margin: 0;
}
#main-container {
display: flex;
background-color: ##f3f3f3;
width: 100%;
height: 100%;
}
.main-container-right {
width: 100%;
height: 800px;
position: relative;
}
#main-nav {
width: 100px;
height: 800px;
background-color: #f3f3f3;
position: sticky;
display: flex;
flex-direction: column;
border: 1px solid #c4c4c4;
box-shadow: 0px 4px 10px 10px rgba(0, 0, 0, 0.25);
z-index: 0;
}
#header {
display: flex;
height: 30px;
width: 100%;
box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25);
z-index: 1;
position: sticky;
}
<div id="main-container">
<nav id="main-nav">
</nav>
<div class="main-container-right">
<header id="header">
</header>
</div>
</div>
I tried to add z-index and positioning the elements, it didn't seem to work. Is there any fix for it?
Here is the problem in a CodePen: https://codepen.io/biljx/pen/rNzwwqd
EDIT: I couldn't fix the z-index problem but managed to get shadow like the original design by using drop-shadow instead of box-shadown filter: drop-shadow(0px 30px 10px rgba(0, 0, 0, 0.25) );
#main-nav {
width: 100px;
height: 800px;
background-color: #f3f3f3;
position: sticky;
display: flex;
flex-direction: column;
border: 1px solid #c4c4c4;
/*box-shadow: 0px 4px 10px 10px rgba(0, 0, 0, 0.25);*/
filter: drop-shadow(0px 30px 10px rgba(0, 0, 0, 0.25) );
z-index: 0;
}
I can't figure out why all these manipulations with z-index? The blocks are already in the correct order. But, as long as you have a transparent #header, the shadow of #main-nav will be visible. So just add a background color for the #header:
* {
margin: 0;
}
#main-container {
display: flex;
width: 100%;
height: 100%;
background-color: #f3f3f3;
}
.main-container-right {
position: relative;
width: 100%;
height: 800px;
}
#main-nav {
position: sticky;
display: flex;
flex-direction: column;
width: 100px;
height: 800px;
border: 1px solid #c4c4c4;
background-color: #f3f3f3;
box-shadow: 0px 4px 10px 10px #0004;
}
#header {
position: sticky;
display: flex;
height: 30px;
width: 100%;
background-color: #f3f3f3;
box-shadow: 0px 4px 4px #0004;
}
<div id="main-container">
<nav id="main-nav">
</nav>
<div class="main-container-right">
<header id="header">
</header>
</div>
</div>

overlap two div elements

I've got a basic html that contain such lines
<div id="circle">
<div id="slider"></div>
</div>
<div id="audio-player-core" class="controls">
<img src="" alt="nothing" width="65px" height="65px">
</div>
And css
#circle {
width: 100px;
height: 100px;
border: 2px solid rgba(0,0,0,0.5);
border-radius: 100%;
float: left;
margin-left: 10px;
}
#slider {
position: relative;
height: 30px;
width: 30px;
background: rgba(0,0,0,0.5);
border-radius: 100%;
cursor: pointer;
}
.controls {
position: relative;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
z-index: 99;
background-color: transparent;
width: 500px;
margin-left: 20px;
}
#audio-player-core {
border: 1px solid;
border-radius:0 10px 10px 0;
border-color: rgba(0,0,0,0.5);
}
But I cannot make them overlap each other (specifically I want for rectangle to start at the center of the circle while hiding part of circle inside). When I try to move one via margin - another moves and so on.
jsfiddle
How to overlap them?
Use positioning. For example,
#audio-player-core {
border: 1px solid;
border-radius:0 10px 10px 0;
border-color: rgba(0,0,0,0.5);
position: absolute;
left: 50px;
top: 60px;
}
#circle {
width: 100px;
height: 100px;
border: 2px solid rgba(0,0,0,0.5);
border-radius: 100%;
float: left;
margin-left: 10px;
}
#slider {
position: relative;
height: 30px;
width: 30px;
background: rgba(0,0,0,0.5);
border-radius: 100%;
cursor: pointer;
}
.controls {
position: relative;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
z-index: 99;
background-color: transparent;
width: 500px;
margin-left: 20px;
}
#audio-player-core {
border: 1px solid;
border-radius:0 10px 10px 0;
border-color: rgba(0,0,0,0.5);
position: absolute;
left: 50px;
top: 60px;
}
<div id="circle">
<div id="slider"></div>
</div>
<div id="audio-player-core" class="controls">
<img src="" alt="nothing" width="65px" height="65px">
</div>

HTML Layout over background DIV

I am trying to achieve the layout in the image below. The hidden-container div is positioned at 0, 0 on the parent main-container div and shown on button click.
I have done a mock up fiddle here.. The col size is smaller so it is easier to see in the fiddle.
.content {
margin: 50px auto 0 auto;
}
#main-container {
width: 100%;
max-width: 500px;
max-height: 200px;
overflow: hidden;
margin: 50px auto 0 auto;
}
#hidden-container {
padding: 0;
max-width: 500px;
max-height: 200px;
width: 100%;
height: 100%;
left: 0;
top: 0;
z-index: 1047;
}
#plyr-container {
padding: 0;
max-width: 300px;
max-height: 200px;
width: 100%;
height: 100%;
left: 0;
top: 0;
z-index: 1048;
background-color: red;
}
#info-container {
max-width: 300px;
max-height: 200px;
width: 100%;
height: 100%;
z-index: 1048;
right: 0;
top: 0;
box-sizing: border-box;
-webkit-box-shadow: -4px 0px 5px 0px rgba(50, 50, 50, 0.3);
-moz-box-shadow: -4px 0px 5px 0px rgba(50, 50, 50, 0.3);
box-shadow: -4px 0px 5px 0px rgba(50, 50, 50, 0.3);
}
#plyra,
#plyrb {
padding: 0;
text-align: left;
position: absolute;
max-width: 300px;
max-height: 200px;
width: 100%;
height: 50%;
z-index: 1049;
}
#plyra {
left: 0;
top: 0;
height: 50%;
background-color: green;
}
#plyrb {
left: 0;
top: 50%;
height: 50%;
border-top: 1px solid black;
background-color: yellow;
}
<div class="content">
<div id="main-container">
<div id="hidden-container">
<div id="plyr-container">
<div id="plyra"></div>
<div id="plyrb"></div>
</div>
<div id="info-container"></div>
</div>
</div>
</div>
Any help is appreciated.
You can do this using flexbox. I did some modification with changing the # to class instead. You have some unnecessary properties, like z-index, top, left. Those properties won't work unless you have absolute or relative on the element. You don't need them to position it and in this particular case they really do nothing. Is this something you where looking for?
I strongly recommend reading this article on css-tricks.com about flexbox.
DEMO: Fiddle
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
.content {
margin: 50px auto 0 auto;
}
.main-container {
width: 100%;
overflow: hidden;
margin: 50px auto 0 auto;
background-color: deepskyblue;
}
.hidden-container {
width: 100%;
height: 100%;
display: flex;
flex-direction: row;
background-color: lightcoral;
}
.plyr-container {
flex-basis: 100%;
flex-grow: 1;
min-height: 300px;
display: flex;
flex-direction: column;
background-color: red;
}
.info-container {
flex-basis: 300px;
flex-grow: 1;
flex-shrink: 0;
-webkit-box-shadow: -4px 0px 5px 0px rgba(50, 50, 50, 0.3);
-moz-box-shadow: -4px 0px 5px 0px rgba(50, 50, 50, 0.3);
box-shadow: -4px 0px 5px 0px rgba(50, 50, 50, 0.3);
background-color: deeppink;
}
.plyra,
.plyrb {
text-align: left;
flex-basis: 50%; //use this instead of width
flex-grow: 1;
flex-shrink: 0;
}
.plyra {
background-color: green;
}
.plyrb {
border-top: 1px solid black;
background-color: yellow;
}
<div class="content">
<div class="main-container">
<div class="hidden-container">
<div class="plyr-container">
<div class="plyra">a</div>
<div class="plyrb">a</div>
</div>
<div class="info-container">d</div>
</div>
</div>
</div>
Refer this as an example you could even do that using display:inline-block, along-with css calc() function to minus the width of 300px from overall container to align two column i.e col1 and col2 as below,
#container {
width: 100%;
height: 100vh;
font-size: 0;
}
#container > .col1 {
width: calc(100% - 300px);
height: 100%;
background: #111;
display: inline-block;
}
#container > .col1 > .c1 {
width: 100%;
height: 50%;
background: pink;
display: inline-block;
}
#container > .col1 > .c2 {
width: 100%;
height: 50%;
background: lightblue;
display: inline-block;
}
#container > .col2 {
width: 300px;
height: 100%;
background: yellow;
display: inline-block;
}
<div id="container">
<div class="col1">
<div class="c1"></div>
<div class="c2"></div>
</div>
<div class="col2"></div>
</div>

Is it possible to add image as box shadow with css?

Is it possible to add image as box shadow, for example to put image with dots instead of standard shadow?
https://i.stack.imgur.com/DOJGh.png
or somehow to replace shadow from picture with dots?
to get effect like this on picture down here
http://prntscr.com/fvjnht
Did you want something like this? It's not exactly box-shadow, but it imitates it.
You can set whatever image you like as a background for .image::after.
html, body {
margin: 0;
}
body {
width: 100vw;
height: 100vh;
}
.contain {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.image{
position: relative;
width: 200px;
height: 200px;
background-image: url(http://via.placeholder.com/200x200);
}
.image::after {
content: '';
background: linear-gradient(to bottom, #333, red);
position: absolute;
width: 100%;
height: 100%;
bottom: -10px;
right: -10px;
z-index: -1;
}
<div class="contain">
<div class="image"></div>
</div>
I think this is exactly what you are looking for:
body {
background: black;
}
#logo {
width: 200px;
height: 200px;
display: block;
position: relative;
}
#logo::after {
content: "";
background: url("https://rfclipart.com/image/big/3f-a9-1a/red-dotted-halftone-background-Download-Royalty-free-Vector-File-EPS-183199.jpg");
opacity: 0.4;
top: 0;
left: 0;
bottom: 0;
right: 0;
position: absolute;
border-radius: 50%;
z-index: -1;
}
img {
width: 90%;
height: 90%;
padding: 5%;
display: block;
float: left;
border-radius: 50%;
box-shadow: 0px 0px 40px #ccc;
-moz-box-shadow: 0px 0px 40px #ccc;
-webkit-box-shadow: 0px 0px 40px #ccc;
}
<div id="logo">
<img src="http://icons.iconarchive.com/icons/graphicloads/colorful-long-
shadow/256/User-icon.png" alt=""/>
</div>
Kind of like this?
.image_carousel img {
margin-right: 14px;
display: block;
float: left;
box-shadow: 3px 3px 1px #ccc;
-webkit-box-shadow: 3px 3px 1px #ccc;
-moz-box-shadow: 3px 3px 1px #ccc;
}
<div class="image_carousel"><img src="//placehold.it/300/f80/fff" alt=""/></div>
Credit goes to Joseph Marikle.
Like this?
span {
border: 2px dotted red;
display: inline-block;
}
img {
padding: 0;
margin: 0;
display: block;
}
<span class="dotted-border"><img src="http://placehold.it/200"/></span>