How to display a box-shadow through a semi-transparent div? - html

I have a div element with this css :
height: 50px;
width: 50px;
background-color: rgba(0, 0, 0, 0.5);
box-shadow: 20px 20px 5px red;
And despite the fact that it's semi transparent, I can't see the red shadow under the div. Is there any way to display it ?
edit : as it's probably a rendering issue, I tested in Google Chrome, Firefox and IE, same result.

You can not get this with a box-shadow, as far as I know.
You can get it with a pseudo element:
.test {
height: 50px;
width: 50px;
background-color: rgba(0, 0, 0, 0.5);
position: relative;
}
.test:after {
content: "";
width: 100%;
height: 100%;
left: 20px;
top: 20px;
background-color: red;
box-shadow: 0px 0px 5px red;
position: absolute;
z-index: -1;
}
I have set a shadow in the pseudo element only for the blurring. The other shadow properties go to the left and top properties of the pseudo element.
fiddle

Related

circular div inner shadow on bottom

I want to have inner shadow only on bottom semicircle of my circular div but shadow seems moving on wrong edges.
Js Fiddle
important part from code which does not work:
box-shadow: inset 3px 3px 3px -1px #000;
What I want is slightly different from those in fiddle :
Some may call this as an inset shadow.
that's what you mean:
.floating-circle{
border-radius: 50%;
background-color: blue;
width: 100px;
padding-top: 100px;
position: absolute;
box-shadow: inset 0 -3px 3px #000;
}
edit, so maybe like this, but without blur:
.floating-circle{
border-radius: 50%;
background-color: #00008B;
width: 100px;
padding-top: 100px;
position: absolute;
overflow: hidden;
}
.floating-circle::after{
border-radius: 50%;
background-color: blue;
width: 100px;
padding-top: 100px;
content:'';
position: absolute;
bottom:5px;
left:0;
}
main element should be "shadow" color, pseudo element should be your main color
3rd try :P with blur, of course You can manipulate blur amount, pesudo element width/height and position to achiver right amount of inner shadow:
.floating-circle{
border-radius: 50%;
background-color: #00008B;
width: 200px;
height: 200px;
position: absolute;
overflow: hidden;
}
.floating-circle::after{
border-radius: 50%;
width: 220px;
height: 220px;
content:'';
position: absolute;
bottom:-5px;
left:-10px;
box-shadow: inset 0 -20px 10px rgba(0,0,0,0.5);
}
i'am afraid there always be some little artifacts, but there are some technics that can make them less visible, translateZ(0) or something like that - try it yourself :)
edit, with percent values:
.floating-circle{
border-radius: 50%;
background-color: #00008B;
width: 70%; /*can be %/px/vw or anything else */
height: 70%; /*can be %/px/vw or anything else */
position: absolute;
overflow: hidden; /*disable this to better see what exactly is happeing with shadow*/
}
.floating-circle::after{
border-radius: 55%;
width: 110%;
height: 110%;
content:'';
position: absolute;
bottom:-5%;
left:-5%;
box-shadow: inset 0 -20px 10px rgba(0,0,0,0.5);
}
you can now set .floatin-circle width/height to percent value or pixels value, and shadow should always work pretty good - you can "tweak" amount of shadow, by rgba opacity color or moving it up and down with "bottom" value or play with box-shadow props :)

Background changes while using transform()

I have this test setup. When I hover over the "Block 1" it should get transformed while keeping its integrity. What I see is that background color is changing. It seems like it's all about background of that .blocks:after element.
(if I comment that, background of element won't change while hovering over).
So, what could cause a problem?
Source - https://jsfiddle.net/1k5e2090/6/
body {
background: #d3d3d3;
}
.blocks {
display: flex;
position: relative;
width: 150px;
height: 55px;
margin: 25px;
justify-content: center;
align-items: center;
color: white;
font-family: 'Helvetica', sans-serif;
font-size: 20px;
}
.blocks#block1 {
background: #4BACC6;
left: 500px;
top: 200px;
}
.blocks#block2 {
left: 500px;
top: -50px;
background: #9BBB59;
}
.blocks#block3 {
left: 200px;
top: -45px;
background: #C0504D;
}
.blocks:after {
position: absolute;
content: '';
background: #F2F2F2;
top: -7px;
left: -7px;
right: -7px;
bottom: -7px;
z-index: -1;
}
.blocks#block1:after {
box-shadow: 3.5px 5.5px 1px -1px rgba(75, 172, 198, 0.45);
}
.blocks#block2:after {
box-shadow: 3.5px 5.5px 1px -1px rgba(155, 187, 89, 0.45);
}
.blocks#block3:after {
box-shadow: 3.5px 5.5px 1px -1px rgba(192, 80, 77, 0.45);
}
.blocks#block1:hover {
transition: 1s ease;
transform: translate(-100px);
}
It's because of the :after behavior on .blocks elements. See this fiddle
.blocks:hover:after { border: 6px solid #fff; background: transparent; z-index: -2; }
.blocks {
border: 7px solid #f2f2f2;
}
i have edited your fiddle https://jsfiddle.net/1k5e2090/9/
you have used the border as a :pseudo element which is not necessary. it is actually creating the problem
In place of using before and after use simple border on blocks and gives box shadow, This is happened because you use position absolute in before and after so when a block moves before and after adopt automatically.Hope it work
Simple use border around the block and remove before and after your problem will solved

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);
}

Box-shadow side-effect blur not smooth. inner square in shadow

I have a slider on my page to change the box-shadow values. At some high blurring values there is an unwanted box-like breaking the shadow, when it is supposed to be a smooth shadow all the way. Is there anyway to avoid this easily? Thanks for the help.
P. S.
I actually need it to work with 'inset' too.
div
{
width:200px;
height:200px;
border-radius: 100px;
background-color:blue;
-webkit-box-shadow: 169px 129px 300px -15px rgba(0,0,0,1);
-moz-box-shadow: 169px 129px 300px -15px rgba(0,0,0,1);
box-shadow: 169px 129px 300px -15px rgba(0,0,0,1);
}
<div></div>
For circular box-shadows the blur cannot go above the width & height of the element. The spread can though.
Since your element is 200px * 200px, the maximum for the blur value is 200px.
Have a look below at the example which doesn't go above 200px and you will see that it creates the box-shadow as expected
div {
width: 200px;
height: 200px;
border-radius: 100px;
background-color: blue;
box-shadow: 169px 129px 200px -15px rgba(0, 0, 0, 1);
}
<div></div>
The spread value can alternatively go above the element width and height and therefore you can make bigger spreads.
div {
width: 200px;
height: 200px;
border-radius: 100px;
background-color: blue;
box-shadow: 169px 129px 0 250px rgba(0, 0, 0, 1);
}
<div></div>
You also didn't really need the prefixes since CSS3 Box-shadows are very well supported now. CanIUse
You can read more about CSS Box shadows in the MDN Documentation
If you want to go outside its dimensions on the shape to be blurred:
The code creates a copy of the circle then colours it black and uses the filter:blur(length);
.circle {
border-radius: 50%;
width: 100px;
height: 100px;
position: relative;
}
.circle::after {
position: absolute;
display: block;
content: " ";
border-radius: 50%;
width: 100%;
height: 100%;
background-color: blue;
}
.circle::before {
position: absolute;
display: block;
content: " ";
border-radius: 50%;
width: 100%;
height: 100%;
background-color: black;
top: 50%;
left: 50%;
-webkit-filter: blur(50px);
filter: blur(50px);
}
<div class="circle"></div>
You can also create inset shadows this way.
How it works:
1. The initial shape is the shadow-color
2. Set overflow:hidden so nothing goes outside the shape.
3. Put a shape on top
4. Blur the shape on top
By doing this the shape under shines through creating the inner shadow effect
.circle {
border-radius: 50%;
width: 100px;
height: 100px;
position: relative;
background-color: black;
overflow: hidden;
}
.circle::before {
position: absolute;
display: block;
content: " ";
border-radius: 50%;
width: calc(100%);
height: calc(100%);
background-color: blue;
transform: translate(-50%, -50%);
top: 50%;
left: 50%;
-webkit-filter: blur(20px);
filter: blur(20px);
}
<div class="circle"></div>

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;
}​