How to use CSS to reproduce the shadow under a device - css

Is it possible to use CSS to reproduce the shadow under the device of the below image?
The following CSS and different variants don't work:
filter: drop-shadow(rgba(22, 22, 22, 0.25) 0px 12px 15px);
The problem is concentrating the shadow under the device and flattening it. The CSS above cannot make the shadow appear as if it's projected on the ground.
Codepen: https://codepen.io/Crashalot/pen/MWYzoJV

A pseudo element is better suited to get this done, see below example:
.object {
margin: 20px;
width: 70px;
height: 140px;
position: relative;
border-style: solid;
background: #E6E6FA;
}
.object:before {
content:"";
z-index: -1;
position: absolute;
bottom: -50%;
width: inherit;
height: inherit;
border-radius: 40%;
background: rgba(0,0,0,.55);
transform: scaleX(1.3) scaleY(0.12);
filter: blur(5px);
}
<div class="object"></div>
Alternatively, you can use box-shadow:
.object {
margin: 20px;
width: 70px;
height: 140px;
position: relative;
border-style: solid;
background: #E6E6FA;
/* This is .shadow-lg from tailwindCSS */
/* See https://tailwindcss.com/docs/box-shadow/ */
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.5), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
}
<div class="object"></div>

Related

Can the shadow from `drop-shadow` only be cast onto specific elements?

The top image below indicates how drop-shadow would be drawn if applied to the top element. I'm trying to determine if it's possible to have the shadow cast only upon certain objects (as illustrated in the bottom image).
I'm open to non-standard solutions on this, but if possible I would prefer to still utilize the drop-shadow filter, as I'd like to use it with non-rectangular shapes as well.
Edit: A fiddle as requested. https://jsfiddle.net/fhrktawm/
Edit 2: Adding a more complex example to illustrate my use case. My purpose here is to indicate additional depth by varying the length of a drop shadows.
You can achieve that by using 4th value of box-shadow or drop-shadow .
And place shadow like in screen shots provided
As shadow of square is always square so it is possible at accurate places only when intersecting part is also square
.box {
width: 100px;
height: 100px;
background: white;
border: 1px solid black;
margin-left: auto;
margin-right: auto;
}
.box-1 {
z-index: 10;
box-shadow: -36px 36px 0 -25px rgba(0, 0, 0, 0.25);
transform: translate3d(60px, 42px, 0);
}
<div class="box box-1"></div>
<div class="box"></div>
Update
You can use ::after property to achieve 2nd effect like this
.box {
width: 100px;
height: 100px;
background: white;
border: 1px solid black;
margin-left: auto;
margin-right: auto;
transform-style: preserve-3d;
}
.box-1 {
box-shadow: -36px 36px 0 -25px rgba(0, 0, 0, 0.25);
transform: translate3d(60px, 42px, 100px);
z-index: 100;
}
.box-1::after {
content: "";
width: 100px;
height: 100px;
position: absolute;
box-shadow: -15px 15px 0 rgba(0, 0, 0, 0.1);
z-index: -100;
transform: translateZ(-100px)
}
<div class="box box-1"></div>
<div class="box"></div>
But as you can see another box is above (because of transform-style: preserve-3d;) as not able to get the box shadow below the box . Tried a different method .
So different approach is done by using box-shadow of another element 2nd one like in below snippet with some variations in shadow
.box {
width: 100px;
height: 100px;
background: white;
border: 1px solid black;
margin-left: auto;
margin-right: auto;
}
.box-1 {
z-index: 10;
box-shadow: -36px 36px 0 -25px rgba(0, 0, 0, 0.25);
transform: translate3d(60px, 42px, 0);
}
.box-2::after {
content: "";
width: 100px;
height: 100px;
position: absolute;
box-shadow: 45px -45px 0 5px rgba(0, 0, 0, 0.1);
z-index: -1;
}
<div class="box box-1"></div>
<div class="box box-2"></div>
At last the desired output can be achieved like this :
.boxContainer {
border: 1px solid black;
width: 160px;
padding: 20px;
}
.box {
width: 100px;
height: 100px;
background: white;
border: 1px solid black;
margin-left: auto;
margin-right: auto;
}
.box-1 {
z-index: 10;
box-shadow: -36px 36px 0 -25px rgba(0, 0, 0, 0.25);
transform: translate3d(60px, 42px, 0);
}
.box-2 {
box-shadow: -10px 10px 0 rgba(0, 0, 0, 0.25);
}
.box-2::after {
content: "";
width: 100px;
height: 100px;
position: absolute;
box-shadow: 45px -45px 0 6px rgba(0, 0, 0, 0.1);
z-index: -1;
}
<div class="boxContainer">
<div class="box box-1"></div>
<div class="box box-2"></div>
</div>
I'm trying to determine if it's possible to have the shadow cast only upon certain objects
To be concise: no, this is not possible using either box-shadow or the drop-shadow() filter.

how to use data-* for tooltip for ellipses element

I have a span which contains ellipses and i want to show the content through tooltip, but the position of the tooltip isn't seem to adjust as i can't apply position relative to the parent (due to ellipses). Here's the code i've tried
.data-tooltip:hover:before{
content: "";
width: 0;
height: 0;
border-top: 5px solid transparent;
border-bottom: 5px solid transparent;
border-bottom: 5px solid rgba(0, 0, 0, 0.6);
position: absolute;
bottom: 82%;
left: 25%;
-webkit-transform: translate(-58%, 41.5%);
transform: translate(-58%, 51.5%);
}
.data-tooltip:hover:after{
content: attr(data-title);
padding: 6px 8px;
color: #fff;
text-align: left;
text-decoration: none;
background-color: rgba(0, 0, 0, 0.6);
border-radius: 4px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
min-height: 32px;
word-wrap: break-word;
position: absolute;
top: unset;
bottom: 75%;
-webkit-transform: translate(-50%, 50%);
transform: translate(-50%, 50%);
}
<span class="data-tooltip" data-tooltip="my tooltip">
ellipsed content
</span>
Here i am using 'before' for tooltip arrow and 'after' for tooltip content, but their positions doesn't seem to adjust either.
i have tried positioning my data-tooltip content relative, but due to overflow:hidden, the tooltip cuts outside the box.
An example below...
This code quoted from Chris Bracco. Please look at this article for detail.
/* Add this attribute to the element that needs a tooltip */
[data-tooltip] {
position: relative;
z-index: 2;
cursor: pointer;
}
/* Hide the tooltip content by default */
[data-tooltip]:before,
[data-tooltip]:after {
visibility: hidden;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
filter: progid: DXImageTransform.Microsoft.Alpha(Opacity=0);
opacity: 0;
pointer-events: none;
}
/* Position tooltip above the element */
[data-tooltip]:before {
position: absolute;
bottom: 150%;
left: 50%;
margin-bottom: 5px;
margin-left: -80px;
padding: 7px;
width: 160px;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
background-color: #000;
background-color: hsla(0, 0%, 20%, 0.9);
color: #fff;
content: attr(data-tooltip);
text-align: center;
font-size: 14px;
line-height: 1.2;
}
/* Triangle hack to make tooltip look like a speech bubble */
[data-tooltip]:after {
position: absolute;
bottom: 150%;
left: 50%;
margin-left: -5px;
width: 0;
border-top: 5px solid #000;
border-top: 5px solid hsla(0, 0%, 20%, 0.9);
border-right: 5px solid transparent;
border-left: 5px solid transparent;
content: " ";
font-size: 0;
line-height: 0;
}
/* Show tooltip content on hover */
[data-tooltip]:hover:before,
[data-tooltip]:hover:after {
visibility: visible;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
filter: progid: DXImageTransform.Microsoft.Alpha(Opacity=100);
opacity: 1;
}
<p style="margin-top:50px">
<span data-tooltip="I’m the tooltip text.">I’m a span with a tooltip.</span>
</p>
Instead of
data-tooltip="my tooltip"
Your data-tooltip attribute should be data-title
That should work now.

How to apply box-shadow around the box including arrow tip?

I am trying to create a tooltip with shadow-box. all works fine. But I am not able to get the shadow to tool tip part( arrow part ) how to get that?
here is my code :
.parent {
position: relative;
border: 1px dashed green;
height: 200px;
}
.toolTip {
position: absolute;
background: #fff;
box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.3);
border-radius: 5px;
width: 100px;
height: 100px;
top: 50px;
left: 50px;
}
.tipPoint {
position: absolute;
top: -15px;
right: 20px;
z-index: 100;
width: 0;
height: 0;
border-left: 15px solid transparent;
border-right: 15px solid transparent;
border-bottom: 15px solid white;
box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.3);
}
<div class="parent">
<div class="toolTip">
<span class="tipPoint"></span>
</div>
</div>
Another solution is to use the filter property set to drop-shadow
Also you'll need to use the :after pseudo selector for the arrow.
Vendor prefixes are available, but unfortunately the feature is not supported by IE. Check for browser compatibility.
.toolTip {
position: absolute;
background: #fff;
width: 100px;
height: 100px;
top: 50px;
left: 50px;
filter: drop-shadow(0px 0px 5px rgba(0, 0, 0, .5));
}
.toolTip:after {
content: " ";
position: absolute;
top: -15px;
right: 20px;
width: 0;
height: 0;
border-left: 15px solid transparent;
border-right: 15px solid transparent;
border-bottom: 15px solid white;
}
<div class="parent">
<div class="toolTip">
</div>
</div>
Tweaking the box-shadow property
The property box-shadow is in fact applied to your element .tipPoint but the shadow is on the bottom of the box. You can easily tweak it's value by changing the shadow's direction on .tipPoint: for example the following looks good:
box-shadow: 1px 0px 6px 0 rgba(0, 0, 0, 0.3);
For more details here's how the property works:
box shadow: <offset-x> <offset-y> <blur-radius> <spread-radius> <color>
.parent {
position: relative;
border: 1px dashed green;
height: 200px;
}
.toolTip {
position: absolute;
background: #fff;
box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.3);
border-radius: 5px;
width: 100px;
height: 100px;
top: 50px;
left: 50px;
}
.tipPoint {
position: absolute;
top: -15px;
right: 20px;
z-index: 100;
width: 0;
height: 0;
border-left: 15px solid transparent;
border-right: 15px solid transparent;
border-bottom: 15px solid white;
box-shadow: 1px 0px 6px 0 rgba(0, 0, 0, 0.3);
}
<div class="parent">
<div class="toolTip">
<span class="tipPoint"></span>
</div>
</div>
Tip: Chrome has a nice shadow editor that you can use to set your values:
Creating an arrow with shadow
If you really want to get it right, there's a way you can make an arrow with shadow. Instead of having a child div tipPoint under .toolTip you can use the :after pseudo-selector. Will create a cube and rotate it 45deg with transform:
.tipPoint {
width: 100px;
height: 100px;
position: relative;
overflow: hidden;
box-shadow: 0 16px 10px -17px rgba(0, 0, 0, 0.5);
}
.tipPoint:after {
content: "";
position: absolute;
width: 50px;
height: 50px;
background: #999;
transform: rotate(45deg); /* Prefixes... */
top: 75px;
left: 25px;
box-shadow: -1px -1px 10px -2px rgba(0, 0, 0, 0.5);
}
<div class="tipPoint"></div>
You can achieve this by using a box-shadow on the main element combined with pseudo elements that overlay each other. This method will result in a seamless drop shadow around the tooltip while using only one element.
See codepen for demo: https://codepen.io/JKudla/pen/GvWYEx
.Tooltip {
width: 15em;
height: 10em;
background: #fff;
box-shadow: 0 0 10px 0 rgba(0,0,0,0.5);
position: relative;
}
.Tooltip:after,
.Tooltip:before {
content: '';
background: #fff;
position: absolute;
height: 1.5em;
}
.Tooltip:before {
width: 1.5em;
right: 1.5em;
transform: rotate(45deg);
top: -0.75em;
box-shadow: 0 0 10px 0 rgba(0,0,0,0.5);
z-index: 0;
}
.Tooltip:after {
width: 3em;
top: 0;
right: 0.75em;
z-index: 1;
}

CSS Page peel bottom together with shadow left and right

I would like to create this page (see image) with css shadow. Is this possible? So to have the page peel css box shadow bottom left and right and the shadow left and right?
You can do this with pseudo elements :before and :after. Creating two new areas which have their own box-shadows and placing them where required you can create the illusion of the shadow getting bigger as the page goes down.
body {
background: lightgrey;
}
div {
background: white;
margin: 40px auto;
height: 500px;
width: 300px;
position: relative;
padding: 10px;
}
div:before,
div:after {
height: 97%;
z-index: -10;
position: absolute;
content: "";
bottom: 15px;
left: 8px;
width: 30%;
top: 2%;
max-width: 300px;
background: transparent;
box-shadow: -10px 0px 5px rgba(0, 0, 0, 0.3);
transform: rotate(1deg);
}
div:after {
transform: rotate(-1deg);
right: 8px;
left: auto;
box-shadow: 10px 0px 5px rgba(0, 0, 0, 0.3);
}
<div>
test
</div>
An alternative is using CSS transforms to change the perspective of a single :before pseudo element.
This was done by Harry **
body {
background: lightgrey;
}
div {
background: white;
margin: 40px auto;
height: 500px;
width: 300px;
position: relative;
padding: 10px;
box-shadow: 10px 0px 5px -10px gray, -10px 0px 5px -10px gray;
}
div:after {
content: '';
position: absolute;
bottom: 10px;
left: 0px;
height: 50%;
width: 100%;
transform-origin: 50% 100%;
transform: perspective(100px) rotateX(1deg);
box-shadow: 5px 0px 10px gray, -5px 0px 10px gray;
z-index: -1;
}
<div></div>
CSS :before & :after

Using pseudoelements for box-shadow, z-index behavior

I use a :before and :after pseudoelements to create a custom-shaped shadow on my text card. I use css like this (jsFiddle):
.card {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
float: left;
width: 310px;
height: 310px;
text-align: center;
color: black;
padding-top: 35px;
border: 1px solid black;
}
.card h1 {
font-size: 15px;
font-weight: bold;
line-height: 17px;
font-style: italic;
margin: 0;
}
.card .text {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
-webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
-moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
margin: 8px auto;
padding: 15px 10px;
font-size: 13px;
text-align: left;
line-height: 14px;
height: 170px;
width: 280px;
background: white;
border-radius: 5px;
position: relative;
color: #222222;
}
.card .text:before,
.card .text:after {
-webkit-box-shadow: 0 0 20px rgba(0, 0, 0, 0.8);
-moz-box-shadow: 0 0 20px rgba(0, 0, 0, 0.8);
box-shadow: 0 0 20px rgba(0, 0, 0, 0.8);
content: "";
display: block;
position: absolute;
z-index: -1;
top: 50%;
bottom: 0;
left: 40px;
right: 40px;
border-radius: 100px/10px;
}
.card .text:after {
-webkit-transform: skew(8deg) rotate(3deg);
-moz-transform: skew(8deg) rotate(3deg);
transform: skew(8deg) rotate(3deg);
right: 10px; left: auto;
}
So far so good. Problems start, when i add some background to my .card element, for example background: #0aabff (jsFiddle #2). Notice, pseudo-elements shadow around .text disappeared.
I tried solving this by adding z-index to my .text element, but then, instead of being behind my .text element, my :before, :after are displayed before it, despite having a z-index: -1; property (jsFiddle #3).
This makes little sense to me, and i still don't know how to solve this kind of problem. Perhaps, there is some kind of workaround, or another way to get the kind of shadow i need (original idea is the courtesy of css-tricks.com);
You can add a z-index lower than -1 to your card class.
.card {
z-index:-2;
position:relative;
}
This is because your z-index of your pseudo-elements is lower than the default z-index value of card. By default is the background transparent and you may see the shadow. When you add a background-color then this is positioned above your pseudo-elements.
See http://jsfiddle.net/71thws1a/3/
The problem lies in the stacking of css as mentioned by #Doodlebunch

Resources