Stacking div over another div - html

I'm trying to achieve something like the image I've attached
And this is what I'm trying to do in css but couldn't get it to work.
#div_1 {
width: 90%;
background: #FBFBFB;
box-shadow: 1px 1px 30px rgba(0, 0, 0, .1);
}
#div_2 {
height: 110%;
width: 30%;
margin-top: -5%;
margin-left: 60%;
vertical-align: top;
background: #FBFBFB;
box-shadow: 1px 1px 30px rgba(0, 0, 0, .1);
}
<div id="div_wrapper">
<div id="div_1">
<div id="div_2"></div>
</div>
</div>

Give position: relative to the parent and position: absolute to the child element, which will make sure that the child is positioned relative to the parent element. Then you can place it wherever you want based on the appropriate top and left positioning properties which replaced the unnecessary margins:
#div_1 {
position: relative; /* added */
width: 90%;
background: #FBFBFB;
box-shadow: 1px 1px 30px rgba(0,0,0,.1);
}
#div_2 {
position: absolute; /* added */
height: 110%;
width: 30%;
top: -5%; /* modified */
left: 60%; /* modified */
background: #FBFBFB;
box-shadow: 1px 1px 30px rgba(0,0,0,.1);
}
<div id="div_wrapper">
<div id="div_1">
Div 1
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<div id="div_2">
Div 2
</div>
</div>
</div>

You can try something like below snippet. You need not mention .child div's height as it will be calculated when you set top and bottom.
.parent {
position: relative;
width: 80%;
height: 80vh;
margin: 5% auto;
background: #fff;
box-shadow: 0px 0px 5px #000;
}
.child{
position: absolute;
top:-5%;
bottom:-5%;
right: 10%;
width: 30%;
background: #fff;
box-shadow: 0px 0px 5px #000;
}
<div class="parent">
<div class="child">
</div>
</div>

What you need to do is to set your wrapper div position as relative and set it's display property to block.
Now you can set your desired width and height to the wrapper.
Wrapper is marked with red dashed line.
Now you have to set the height for the child elements to expand to their wrapper div.
You can do that by providing a
height: 100%
to div1
Next is to align child items to their parent element.
Usually to align a child element to it's parent you can set the position of parent as relative and child as absolute.
You can set position: absolute to div2 and position:relative to div1
I would suggest to set the location of div2 using top and left rather than margin-top and margin-left.
Here is a very nice explanation about positions and the common mistakes:
https://css-tricks.com/absolute-relative-fixed-positioining-how-do-they-differ/
and here https://css-tricks.com/absolute-positioning-inside-relative-positioning/ you can find some tips on how to position parent and child elements.
I have modified your code a bit, have a look at it here:
#div_wrapper {
display: block;
position: relative;
height: 200px; /* Change to whatever height you like */
width: 400px; /* Change to whatever width you like */
top: 50px; /* Just for demo */
left: 10px; /* Just for demo */
}
#div_1 {
display: block;
position: relative; /* Added */
width: 90%;
height: 100%; /* Added */
background: #FBFBFB;
box-shadow: 1px 1px 30px rgba(0, 0, 0, .1);
}
#div_2 {
position: absolute; /* Added */
height: 110%;
width: 30%;
top: -5%; /* Modified */
left: 60%; /* Modified */
vertical-align: top;
background: #FBFBFB;
box-shadow: 1px 1px 30px rgba(0, 0, 0, .1);
}
<div id="div_wrapper">
<div id="div_1">
<div id="div_2"></div>
</div>
</div>

Try following code it can be work for you may be. You will see effect when "#div_1" have content or height.
#div_1 {
width: 90%;
position: relative;
background: #FBFBFB;
box-shadow: 1px 1px 30px rgba(0, 0, 0, .1);
}
#div_2 {
width: 30%;
position: absolute;
top: -5%;
bottom: -5%;
left: 60%;
vertical-align: top;
background: #FBFBFB;
box-shadow: 1px 1px 30px rgba(0, 0, 0, .1);
}

<style type="text/css">
#div_wrapper{
position: relative;
width: 100%;
}
#div_1 {
width: 90%;
background: #FBFBFB;
box-shadow: 1px 1px 30px rgba(0, 0, 0, .1);
height: 300px;
margin-top: 100px;
position: relative;
}
#div_2 {
position: absolute;
height: 120%;
width: 30%;
right: 5%;
top:-10%;
background: #FBFBFB;
box-shadow: 1px 1px 30px rgba(0, 0, 0, .1);
}
</style>
<div id="div_wrapper">
<div id="div_1"> div 1
<div id="div_2">div 2</div>
</div>
</div>

For this layout it would be good, if you use position:absolute for div_2 ID and position:relative for div_1 ID, this will let you position the child div anywhere relative to the parent and it is dependent on the height of div_1.
#div_1 {
width: 90%;
background: #FBFBFB;
display:inline-block;
position:relative;
box-shadow: 1px 1px 30px rgba(0, 0, 0, .1);
}
#div_2 {
width: 30%;
position:absolute;
right:10%;
top:-10px;
bottom:-10px;
vertical-align: top;
background: #FBFBFB;
box-shadow: 1px 1px 30px rgba(0, 0, 0, .1);
}
#div_wrapper{
text-align:center;
margin:50px 0px;
}
<div id="div_wrapper">
<div id="div_1">test
<div id="div_2">test2</div>
</div>
</div>

Related

How to hide shadow between two adjoined divs

I have two divs on top of each other (adjoined) and they booth as one unit shall have one box-shadow. Now the upper div gives shadow on the lower div which I don't want. I have tried to manipulate it with a "z-index:2" to be more on top but no luck.
I would like to hide the bottom shadow of the upper div and hide the top shadow of the lower div
Also I don't want the shadow to fold into the adjoined sides. The two divs should be one unit having one shadow
In my example here I have simpified the html
<div class="upper-box" style="width:100px;height:100px;">
</div>
<div class="lower-div" style="width:100px;height:100px;">
</div>
In the jsfiddle the css is all in original and here goes all the work of change.
.upper-box {
border-top: 0 none;
margin-bottom: 2px;
margin-top: -2px;
overflow: auto;
position: relative;
padding-top: 0;
/* Expanded panel gets emphasized by a shadow */
box-shadow: 0px 6px 50px 7px rgba(255,255,255,0.75),
0px 6px 50px 7px rgba(88,88,88,0.75),
0px 6px 50px 7px rgba(88,88,88,0.75),
0px 6px 50px 7px rgba(88,88,88,0.75)
;
z-index: 3;
border-style: solid;
border-color: #000000;
border-width: 0px;
position: relative;
}
.lower-div {
border-bottom: 0px;
box-shadow: 0px 6px 50px 7px rgba(88,88,88,0.75);
z-index: 2;
border-style: solid;
border-color: #000000;
border-width: 0px;
}
I would like to hide the bottom shadow of the upper div and hide the top shadow of the lower div
Also I don't want the shadow to fold into the adjoined sides. The two divs should be one unit having one shadow
Here is my live demo
https://jsfiddle.net/y289sdeb/
You could use a pseudo element, like this
.upper-box {
position: relative;
width: 100px;
height: 100px;
background: white;
}
.lower-div {
position: relative;
width: 100px;
height: 100px;
background: white;
}
.upper-box::after,
.lower-div::after {
content: '';
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
box-shadow: 0px 6px 50px 7px rgba(88, 88, 88, 0.75);
z-index: -1;
}
<div class="upper-box">
</div>
<div class="lower-div">
</div>
Based on a comment, a wrapper can be used
.wrapper {
position: relative;
display: inline-block;
}
.upper-box {
position: relative;
width: 100px;
height: 100px;
}
.lower-div {
position: relative;
width: 100px;
height: 100px;
}
.wrapper::after {
content: '';
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
box-shadow: 0px 6px 50px 7px rgba(88, 88, 88, 0.75);
z-index: -1;
}
<div class="wrapper">
<div class="upper-box">
</div>
<div class="lower-div">
</div>
</div>

Box shadow on adjacent elements with variable width

I'm trying to add a box shadow on two elements, each with variable width. My desired result looks like this:
I've been trying to get to this result with a pseudo element covering the overlapping box shadows, but because they need to have transparency, I can't seem to find a solution in which there are neither small overlaps at the edges of the boxes nor the pseudo element adjusts to the correct width.
The top box does also not necessarily need a top border to solve my problem.
Fiddle
HTML:
<div>
<p></p>
</div>
<div>
<p></p>
</div>
SCSS:
div {
display: inline-block;
margin: 75px;
width: 200px;
height: 50px;
position: relative;
p {
position: absolute;
top: 100%;
left: 0;
height: 300px;
width: 250px;
}
&, p {
background: #ededed;
}
}
div:last-child p {
width: 150px
}
div {
box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.2);
p {
box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.2);
}
}
Edit:
Normally I wouldn't consider JS for layout but since in my particular case the boxes won't be visible until a user interaction occurs, I've used a script to solve my problem.
The script figures out if the top element is bigger than the bottom one when the dom is ready and adds a "big" or "small" class to it respectively. By knowing that, we know which element the pseudo-element's width should inherit. As long as the elements don't get resized in a way that would change which element is bigger, this works fine.
There is also a much cleaner solution without the need for JS and one pseudo element less in case one only needs box-sizing blur and no spread.
Fiddles:
Blur and spread combined (JS),
Only blur, no spread (No JS)
The end result is not quite perfect as you can see in this screenshot where all the white background is replaced with black:
When you look at the left box's top left, you can see that the border shadow has a slight curve.
Anyway, it's close enough to me.
If someone finds a solution with a similar result as in the first fiddle using only css, I would really appreciate it.
You have an easy solution for this, but it is an experimental feature and it has limited support.
Using a filter: drop shadow on the base element, the drop shadow applies to the composite result of this element, and all the descendants
div {
display: inline-block;
margin: 75px;
width: 150px;
height: 50px;
position: relative;
-webkit-filter: drop-shadow(0px 0px 5px rgba(255, 0,0,0.7));
filter: drop-shadow(0px 0px 2px red);
}
div p {
position: absolute;
top: 100%;
left: 0;
height: 300px;
width: 250px;
margin: 0px;
}
div, div p {
background: #ededed;
}
#second p {
width: 100px;
}
<div>
<p></p>
</div>
<div id="second">
<p></p>
</div>
An alternate approach, that will run in any browser, using pseudo elements for the shadows:
div {
display: inline-block;
margin: 75px;
width: 150px;
height: 50px;
position: relative;
}
div p {
position: absolute;
top: 100%;
left: 0;
height: 300px;
width: 250px;
margin: 0px;
}
div, div p {
background: #ededed;
}
#second p {
width: 100px;
}
div:after, p:after {
content: "";
position: absolute;
left: 0px;
top: 0px;
right: 0px;
bottom: 0px;
box-shadow: 0px 0px 2px 6px rgba(0,255,0,0.7);
z-index: -10;
}
<div>
<p></p>
</div>
<div id="second">
<p></p>
</div>
An alternate approach is to clip the shadows. That is poorly suported, and needs lots of manual adjustements, but the end result is probably the best looking.
Demo working only in webkit
div {
display: inline-block;
margin: 75px;
width: 300px;
height: 50px;
position: absolute;
}
div p {
position: absolute;
top: 100%;
left: 0;
height: 100px;
width: 200px;
margin: 0px;
}
div, div p {
background: #ededed;
}
div:after, p:after {
content: "";
position: absolute;
left: 0px;
top: 0px;
right: 0px;
bottom: 0px;
box-shadow: 0px 0px 15px 15px rgba(255,0,0,0.2);
z-index: -10;
}
p:after {
-webkit-clip-path: polygon(0% 30px, 230px 30px, 260px 60px, 100% 100%, 0% 100%);
}
div:after {
-webkit-clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 260px 100%, 230px 80px, 0% 80px);
}
<div>
<p></p>
</div>
If you really need a plain color background instead of a background image, this shall work:
I used a div to create the empty area.
<div class="shad">
<div class="cover1"></div>
<p></p>
</div>
<div class="shad">
<div class="cover2"></div>
<p></p>
</div>
The paragraphs are set to same size as div.shad.
div.shad {
display: inline-block;
margin: 75px;
width: 250px;
height: 350px;
position: relative;
background: #ededed;
p {
position: absolute;
top: 0%;
left: 0;
width: 250px;
height: 350px;
}
.cover1 {
position: relative;
float: right;
margin-top: -2px;
margin-right: -2px;
width: 50px;
height: 50px;
background-color: white;
border-left: 2px solid rgba(0, 0, 0, 0.2);
border-bottom: 2px solid rgba(0, 0, 0, 0.2);
}
.cover2 {
position: relative;
float: right;
margin-top: 50px;
margin-right: -2px;
width: 50px;
height: 300px;
background-color: white;
border-top: 2px solid rgba(0, 0, 0, 0.2);
border-left: 2px solid rgba(0, 0, 0, 0.2);
}
}
div.shad {
box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.2);
}

Content overflows instead of expainding div

I've been struggling with this for the past day and I can't seem to understand (nor fix) this problem.
The problem is that the content overflows the "sidebar" div instead of expanding it, when there's less "main" content than "sidebar" content. (As you can see in the following image).
Here's a JSFiddle!
The #sidebar is position: absolute; since I'm using left: 0; and left: -200; to show and hide the sidebar. The #sidebar-handle is also crucial as I have a click event listener and a hover animation connected to it, for the purpose of toggling show and hide for the #sidebar. (When toggling show and hide I also do change the margin-left of #main.
Does anybody have a solution?
I'm of course searching for a pure CSS solution and a solution which works in the major browsers.
CSS
html, body {
height: 100%;
min-height: 100%;
margin: 0;
padding: 0;
color: #333;
background-color: #EEE;
}
#container {
height: 100%;
min-height: 100%;
}
#header {
height: 50px;
background-color: #303030;
-webkit-box-shadow: 0 3px 10px rgba(0, 0, 0, 0.5);
-moz-box-shadow: 0 3px 10px rgba(0, 0, 0, 0.5);
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.5);
}
#header-content {
height: 100%;
}
#sidebar {
width: 210px;
min-height: 100%;
position: absolute;
left: 0;
top: 50px;
bottom: 0;
background-color: #404040;
-webkit-box-shadow: 3px 4px 10px rgba(0, 0, 0, 0.5);
-moz-box-shadow: 3px 4px 10px rgba(0, 0, 0, 0.5);
box-shadow: 3px 4px 10px rgba(0, 0, 0, 0.5);
}
#sidebar-content {
width: 200px;
position: absolute;
left: 0;
}
#sidebar-handle {
width: 10px;
position: absolute;
right: 0;
top: 0;
bottom: 0;
background-color: #303030;
border-left: 1px solid #272727;
}
#main {
margin-left: 210px;
padding: 30px;
}
ul {
margin: 0;
padding-left: 0;
list-style: none;
}
li {
margin: 0;
margin-top: 16px;
background-color: #AAA;
}
p {
margin-top: 0;
}
HTML
<div id="container">
<div id="header">
<div id="header-content"></div>
</div>
<div id="content">
<div id="sidebar-container">
<div id="sidebar">
<div id="sidebar-content">
<ul>
<!-- lots of li tags for testing -->
</ul>
</div>
<div id="sidebar-handle"></div>
</div>
</div>
<div id="main">
<!-- some random content for testing -->
</div>
</div>
</div>
Remove the bottom: 0 from the sidebar, that limits it to the height of the window.
Remove the absolute positioning on the sidebar-content, so that it's not taken out of the flow. That way it can affect the size of the sidebar.
Demo: http://jsfiddle.net/Guffa/gfu1snhm/3/
I don't know if this has some unwanted effect in some other situation, but it solves this situation, and should help you see why it does what it does.
Remove the line with absolute and set margin:0;

Positioning DIVs with CSS

I have two DIVs inside each other. The inner DIV contains an image. I'm trying to add a floating text over that image in the top right corner. I can't figure out how to make that text to use inner DIV's positions instead of the outer one.
Here is what I got so far
CSS:
html {
background: #EEF0F3;
}
.outer {
background: #FFFFFF;
border-radius: 4px 4px 4px 4px;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
margin: 0 auto;
padding:20px 0px;
position: relative;
width: 680px;
text-align: center;
margin-bottom: 20px;
}
.inner {
position: relative;
}
h2 {
position: absolute;
top: 0px;
right: 0px;
}
h2 span {
color: white;
font: bold 24px Helvetica, Sans-Serif;
letter-spacing: -1px;
background: rgba(255, 0, 0, 0.5);
padding: 0px 10px;
}
HTML:
<div class="outer">
<div class="inner">
<h2><span>Title 1</span></h2>
<img src="1.jpg">
</div>
</div>
And here is the code in JSFiddle
http://jsfiddle.net/UM8ea/
If I set positioning to:
h2 {
position: absolute;
top: 20px;
right: -20px;
}
I get the desired result, but that feels like workaround rather than a solution.
Its very simple.
Check this fiddle
.outer {
background: #FFFFFF;
border-radius: 4px 4px 4px 4px;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
margin: 0 auto;
padding:20px 0px;
position: relative;
width: 680px;
text-align: center;
margin-bottom: 20px;
}
for h2
h2
{
position: absolute;
top: 5px;
right: 20px;
margin:0;
}
You have this behaviour because .outer is wider than the image, and then, .inner too. The h2 is positioned related to .inner, and go to right.
If you set .outer to have 640px width (as the image) you get the desired result.
Other solution is to set margin: 0 20px; on .inner
If you want the text positioned all top the image you can set h2 {margin:0;} in both cases.

Overlap an img completely with another div

I am trying to achieve this effect where a photo gets a repeating pattern overlayed over the entire photo when the user place his mouse over the photo.
Problem: I do not seem to be able to make the overlay div overlay the photo completely. How should this be done?
JSfiddle: http://jsfiddle.net/KDyKH/2/
Edit: Updated the fiddle
CSS
#container {
position: relative;
padding: 10px;
width: 1000px;
height: 500px;
background: blue;
}
.photo_box {
padding: 8px 10px 11px 10px;
background: #fff;
-webkit-box-shadow: 1px 1px 6px rgba(50, 50, 50, 0.25);
-moz-box-shadow: 1px 1px 6px rgba(50, 50, 50, 0.25);
box-shadow: 1px 1px 6px rgba(50, 50, 50, 0.25);
border-radius: 5px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
display: inline-block;
position: relative;
}
.photo {
position: absolute;
z-index: 0;
margin-bottom: 13px;
border-radius: 5px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
}
.photo_tint {
width: 100%;
height: 100%;
position: absolute;
z-index: 100;
background: red;
-moz-opacity: 0.70;
opacity: 0.70;
-ms-filter:"progid:DXImageTransform.Microsoft.Alpha"(Opacity=70);
}​
HTML
<div id="container">
<div class="photo_box">
<img src='http://www.kurzweilai.net/images/Google-logo.jpg' class="photo">
<div class="photo_tint"></div>
</img>
</div>
</div>​
In addition to adding left and top properties to .photo_tint, you also need to make .photo_box relatively positioned (it wasn't before you edited your question).
.photo_box {
position: relative;
}
.photo_tint {
left:0;
right:0;
}​
http://jsfiddle.net/KDyKH/5/
The absolute position's left/top/right/bottom attributes work off the last element higher in the hierarchy with position set to relative or absolute. If no parent elements have position set to relative/absolute, the body is used. In your case, the closest relatively positioned element was #container, so when left and top were set on .photo_tint it used #container's origin and not .photo_box's origin as needed to achieve the desired effect.
Additionally, if an element is set to position:absolute, and no left/top/right/right properties are set, the element will not behave as absolute (see this question).
.photo_tint {
position: absolute;
z-index: 100;
background: red;
top:0; left:0;
width:100%; height:100%;
}​
???
http://jsfiddle.net/tFbbM/1/
Just position the photo_tint div using top and left. http://jsfiddle.net/OhMrBigshot/gEdJu/
z-index:-1 on the image or z-index:2 on the div
#container {
position: relative;
width: 500px;
height: 500px;
background: blue;
}
.photo {
position: relative;
width: 300px;
height: 100px;
background: green;
}
.photo_tint {
position: absolute;
z-index: 1;
background: red;
width: 300px;
height: 100px;
top:0px;
}​