ChatGPT解决这个技术问题 Extra ChatGPT

How can I add a box-shadow on one side of an element?

I need to create a box-shadow on some block element, but only (for example) on its right side. The way I do it is to wrap the inner element with box-shadow into an outer one with padding-right and overflow:hidden; so the three other sides of the shadow are not visible.

Is there some better way to achieve this? Like box-shadow-right?

EDIT: My intentions are to create only the vertical part of the shadow. Exactly the same as what repeat-y of the rule background:url(shadow.png) 100% 0% repeat-y would do.

considering css' limited tools in terms of box-shadows I think your approach is already quite good. It's not too cluttering and has a fairly small impact in terms of semantics: just one meaningless div.
Here is a nice css side-shadow : stackoverflow.com/a/20596554/1491212
This is hands down the best answer! \o/ stackoverflow.com/a/62366856/358532 Thanks!

K
Kyle

Yes, you can use the shadow spread property of the box-shadow rule:

.myDiv { border: 1px solid #333; width: 100px; height: 100px; box-shadow: 10px 0 5px -2px #888; }

The fourth property there -2px is the shadow spread, you can use it to change the spread of the shadow, making it appear that the shadow is on one side only.

This also uses the shadow positioning rules 10px sends it to the right (horizontal offset) and 0px keeps it under the element (vertical offset.)

5px is the blur radius :)

Example for you here.


Thank you for pointing out something that I didn't know, but my intentions were to create only the vertical part of the shadow. Exactly the same what background:url(shadow.png) 100% 0% repeat-y would do.
@Tillda you should mark this as the answer so it appears on top for others searching for a solution. I almost dismissed this method of styling reading the comments and accepted answer.
This works great if you do not intend for the shadow to attenuate at the corners. I came up with this solution as well myself but in most cases (for a shadow on one side) it is wrong to have the shadow be smaller than the element, thus breaking the illusion (if it were so intended) that said element is "raised" or "3D".
@Mr.Alien Thanks for that, I just removed the prefix as the box-shadow rules was standardized.
but this shadow has no blur, and including blur make it come out from other parts. And if you account for that by reducing spread, it ends prematurely on the side you actually want it. UGHHHHH
L
Luke

clip-path is now (2020) one of simplest ways to achieve box-shadows on specific sides of elements, especially when the required effect is a "clean cut" shadow at particular edges (which I believe was what the OP was originally looking for) , like this:

.shadow-element { border: 1px solid #333; width: 100px; height: 100px; box-shadow: 0 0 15px rgba(0,0,0,0.75); clip-path: inset(0px -15px 0px 0px); }

...as opposed to an attenuated/reduced/thinning shadow like this:

.shadow-element { border: 1px solid #333; width: 100px; height: 100px; box-shadow: 15px 0px 15px -10px rgba(0,0,0,0.75); }

Simply apply the following CSS to the element in question:

box-shadow: 0 0 Xpx [hex/rgba]; /* note 0 offset values */
clip-path: inset(Apx Bpx Cpx Dpx);

Where:

Apx sets the shadow visibility for the top edge

Bpx right

Cpx bottom

Dpx left

Enter a value of 0 for any edges where the shadow should be hidden and a negative value (the same as the box-shadow blur radius - Xpx) to any edges where the shadow should be displayed.


@tillda, dredging up a decade-old question - just wondering whether I correctly interpretted your once-upon-a-time requirement (specifically the cut-off shadow effect) - I was trying to achieve exactly this and came across your question in the process.
Thanks so much! This is perfect!
I'd argue that this is now the best answer for people who don't need to support IE11. Thanks!
Perfect. So much unknown CSS stuff. Almost sound made up when you first see them.
a-m-a-z-i-n-g!!
P
Puyol

My self-made solution which is easy to edit:

HTML:

<div id="anti-shadow-div">
    <div id="shadow-div"></div>
</div>​

css:

#shadow-div{
    margin-right:20px; /* Set to 0 if you don't want shadow at the right side */
    margin-left:0px; /* Set to 20px if you want shadow at the left side */
    margin-top:0px; /* Set to 20px if you want shadow at the top side */
    margin-bottom:0px; /* Set to 20px if you want shadow at the bottom side */
    box-shadow: 0px 0px 20px black; 
    height:100px;
    width:100px;
    background: red;
}

#anti-shadow-div{
    margin:20px;
    display:table;
    overflow:hidden;
}​

Demo:
http://jsfiddle.net/jDyQt/103


Seems somehow the most straight forward one - just the container div is making me unhappy somehow ;)
This is the only real solution. The accepted answer still has blur on top and bottom of the shadow, just at different position.
This didn't work for me in Microsoft Edge or Internet Explorer 11. There was still a bit of shadow on the other sides, depending on the zoom level. Other browsers were fine though.
The answer at stackoverflow.com/a/24220224/238753 worked the same as this but without the browser compatibility issues that this answer has
J
Jacek Kuzemczak

To get the clipped effect on up to two sides you can use pseudo elements with background gradients.

header::before, main::before, footer::before, header::after, main::after, footer::after {
    display:    block;
    content:    '';
    position:   absolute;
    width:      8px;
    height:     100%;
    top:        0px;
}

header::before, main::before, footer::before {
    left:       -8px;
    background: linear-gradient(to left, rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0));
}

header::after, main::after, footer::after {
    right:      -8px;
    background: linear-gradient(to right, rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0));
}

will add a nice shadow-like effect to the left and right of the elements that normally make up a document.


perfect solution, as it adds a shadow effect to one side of an element only without cluttering up the markup.
Compared to the negative spread method this has the advantage of not shrinking at the corners.
@BananaAcid I created a demo for anyone who needs it: jsfiddle.net/jDyQt/1198
Nice, this worked perfectly across Chrome, Safari, Firefox, IE11 & Edge with no side effects for me
r
riegersn

Just use ::after or ::before pseudo element to add the shadow. Make it 1px and position it on whatever side you want. Below is example of top.

footer { margin-top: 50px; color: #fff; background-color: #009eff; text-align: center; line-height: 90px; position: relative; } footer::after { content: ''; position: absolute; width: 100%; height: 1px; top: 0; left: 0; z-index: -1; box-shadow: 0px 0px 10px 1px rgba(0, 0, 0, 0.75); }

top only box shadow


This one still spills over past the edge, but might be what some people want
f
freedomn-m

Here is my example:

.box{ width: 400px; height: 80px; background-color: #C9C; text-align: center; font: 20px normal Arial, Helvetica, sans-serif; color: #fff; padding: 100px 0 0 0; -webkit-box-shadow: 0 8px 6px -6px black; -moz-box-shadow: 0 8px 6px -6px black; box-shadow: 0 8px 6px -6px black; }


a
atiquratik

Here's a little hack that I did.

<div id="element"><!--element that I want an one-sided inset shadow from the bottom--></div> 
<div class="one_side_shadow"></div>

1. Create a <div class="one_side_shadow"></div> right below the element that I want to create the one-side box shadow (in this case I want a one-sided inset shadow for id="element" coming from the bottom)

2. Then I created a regular box-shadow using a negative vertical offset to push the shadow upwards to one-side.

`box-shadow: 0 -8px 20px 2px #DEDEE3;`

R
ROOT

Here is a codepen to demonstrate for each side, or a working snippet:

.boxes { display: flex; flex-wrap: wrap; } .box { margin: 20px; border: 1px solid #ccc; font-family: Helvetica Neue, Arial, sans-serif; font-weight: 100; letter-spacing: 2px; color: #999; display: flex; align-items: center; justify-content: center; text-align: center; flex: 1; padding: 40px; line-height: 1.4em; } .top { box-shadow: 0 -5px 5px -5px #333; } .right { box-shadow: 5px 0 5px -5px #333; } .bottom { box-shadow: 0 5px 5px -5px #333; } .left { box-shadow: -5px 0 5px -5px #333; }

Top Only
Right Only
Bottom Only
Left Only


m
madhairsilence

This could be a simple way

border-right : 1px solid #ddd;
height:85px;    
box-shadow : 10px 0px 5px 1px #eaeaea;

Assign this to any div


t
ter24

This site helped me: https://gist.github.com/ocean90/1268328 (Note that on that site the left and right are reversed as of the date of this post... but they work as expected). They are corrected in the code below.

<!DOCTYPE html>
<html>
    <head>
        <title>Box Shadow</title>

        <style>
            .box {
                height: 150px;
                width: 300px;
                margin: 20px;
                border: 1px solid #ccc;
            }

            .top {
                box-shadow: 0 -5px 5px -5px #333;
            }

            .right {
                box-shadow: 5px 0 5px -5px #333;
            }

            .bottom {
                box-shadow: 0 5px 5px -5px #333;
            }

            .left {
                box-shadow: -5px 0 5px -5px #333;
            }

            .all {
                box-shadow: 0 0 5px #333;
            }
        </style>
    </head>
    <body>
        <div class="box top"></div>
        <div class="box right"></div>
        <div class="box bottom"></div>
        <div class="box left"></div>
        <div class="box all"></div>
    </body>
</html>

A
Ashisha Nautiyal
div {
 border: 1px solid #666;
    width: 50px;
    height: 50px;
    -webkit-box-shadow: inset 10px 0px 5px -1px #888 ;
}

j
jim_kastrin

What I do is create a vertical block for the shadow, and place it next to where my block element should be. The two blocks are then wrapped into another block:

<div id="wrapper">
    <div id="shadow"></div>  
    <div id="content">CONTENT</div>  
</div>

<style>

div#wrapper {
  width:200px;
  height:258px;      
}

div#wrapper > div#shadow {
  display:inline-block;
  width:1px;
  height:100%;
  box-shadow: -3px 0px 5px 0px rgba(0,0,0,0.8)
}

div#wrapper > div#content {
  display:inline-block;
  height:100%;
  vertical-align:top;
}

</style>

jsFiddle example here.


a
alex

Ok, here is one try more. Using pseudo elements and aplying the shadow-box porperty over them.

html:

<div class="no-relevant-box">
  <div class="div-to-shadow-1"></div>
  <div class="div-to-shadow-2"></div>
</div>

sass:

.div-to-shadow-1, .div-to-shadow-2
  height: 150px
  width: 150px
  overflow: hidden
  transition: all 0.3s ease-in-out
  &::after
    display: block
    content: ''
    position: relative
    top: 0
    left: 100%
    height: 100%
    width: 10px
    border: 1px solid mediumeagreen
    box-shadow:  0px 7px 12px rgba(0,0,0,0.3)
  &:hover
    border: 1px solid dodgerblue
    overflow: visible

https://codepen.io/alex3o0/pen/PrMyNQ