46

有没有办法创建一个css box-shadow,无论模糊值如何,阴影只出现在所需的边上?

例如,如果我想创建一个左右两侧有阴影且顶部或底部没有阴影的 div。div 不是绝对定位的,它的高度是由内容决定的。

- 编辑 -

@ricebowl:感谢您的回答。也许您可以帮助创建一个完整的解决方案来解决我对您的解决方案的回复中所述的问题......我的页面设置如下:

<div id="container">
    <div id="header"></div>
    <div id="content"></div>
    <div id="clearfooter"></div>
</div>
<div id="footer"></div>

像这样的CSS:

#container {width:960px; min-height:100%; margin:0px auto -32px auto; 
       position:relative; padding:0px; background-color:#e6e6e6; 
       -moz-box-shadow: -3px 0px 5px rgba(0,0,0,.8), 
       3px 0px 5px rgba(0,0,0,.8);}
#header   {height:106px; position:relative;}
#content   {position:relative;}
#clearFooter {height:32px; clear:both; display:block; padding:0px; margin:0px;}
#footer  {height:32px; padding:0px; position:relative; width:960px; margin:0px 
           auto 0px auto;}
4

9 回答 9

49

您可以定义第四个距离,称为扩展偏移,它将阴影在所有 4 个边上移入或移出。因此,如果您将其设置为模糊距离的负值,这会将阴影向内移动相同的距离,因为模糊会将阴影向外延伸,从而有效地隐藏它。当然,这也会在您希望它出现的一侧将阴影向内移动,因此您需要通过模糊距离增加偏移量来撤消它。IE

box-shadow: (horizontal + blur) 0px (blur) (-blur) color;

所以在你的例子中:

box-shadow: -8px 0px 5px -5px rgba(0,0,0,.8), 8px 0px 5px -5px rgba(0,0,0,.8);
于 2011-05-02T04:04:34.540 回答
12

我有 2 种可能的解决方案可以产生完全预期的效果:某些边缘上的“正常”框阴影,而其他边缘上没有。此问题和其他 SO 问题中列出的许多解决方案会导致阴影“消散”,因为它们靠近没有阴影的边缘,而实际上我相信大多数人都想要一个干净的截止。

但是,这两种解决方案都带有警告。


解决方案 1:剪辑路径(实验性)

如果您愿意使用仅部分支持的实验技术,则可以使用clip-path属性.

在您的情况下,您将使用clip-path: inset(px px px px);从相关边缘计算像素值的位置(见下文)。

#container {
    box-shadow: 0 0 5px rgba(0,0,0,0.8);
    clip-path: inset(0px -5px 0px -5px);
}

这将在以下位置剪辑有问题的 div:

  • 距顶部 0 像素
  • 右边缘外 5 个像素(包括阴影)
  • 距底部 0 像素
  • 左边缘外 5 个像素(包括阴影)

请注意,像素值之间不需要逗号。

不需要绝对定位,div的大小可以灵活。


解决方案 2:剪辑(已弃用)

如果:

  1. 你愿意设置position: absolute有问题的 div
  2. 你知道 div 的尺寸
  3. 或者您不知道 div 的尺寸,但您只愿意移除顶部和/或左侧的阴影

...您可以使用已弃用的 clip属性

您需要使用clip: rect(px, px, px, px);从左上角计算像素值的位置。我使用它来切断顶部的盒子阴影,但保留底部和侧面:

#container {
    position: absolute;
    box-shadow: 0 0 5px rgba(0,0,0,0.8);
    width: 100px;
    height: 100px;
    clip: rect(0px, 105px, 100px, -5px);
}

上面将剪切顶部和底部的盒子阴影,同时留下 5px 左右的盒子阴影。请注意,必须知道 div 的大小。

如果不知道 div 的大小,则此方法仅适用于使用类似的东西来裁剪顶部和左侧的阴影clip: rect(0, 3000px, 3000px, 0);(注意右侧和底部值的巨大值以允许 div 为任意大小)。

于 2016-12-15T22:35:42.127 回答
8

你也可以使用 clip:rect(0px, 210px, 200px, -10px);

可悲的是,我从来没有想出一种方法让它与一个灵活大小的盒子一起工作。

我经常将它用于下拉菜单,我只希望在侧面和底部有阴影。在这种情况下,我只需将右侧和底部剪辑值设置为某个较高的数字,例如

剪辑:矩形(0像素,1000像素,1000像素,-10像素);/* 剪掉盒子阴影的顶部 */

#box{
    box-shadow:             0px 0px 10px rgba(0, 0, 0, 0.7);
    -moz-box-shadow:     0px 0px 10px rgba(0, 0, 0, 0.7);
    -webkit-box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.7);
    clip:rect(0px, 210px, 200px, -10px); /* Clip the top and bottom of the box-shadow off */
    width:200px;
    height: 200px;
    position: absolute;
    top:50px;
    left:50px;
    background:#eee;
}
于 2011-05-28T22:15:49.713 回答
6

有,但它相当脆弱。

使用以下 xhtml:

<div id="wrap">

 <div id="content">

   <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. In sodales justo nec mauris aliquam vitae feugiat magna congue. Morbi dignissim volutpat dui id porttitor. Donec auctor feugiat dolor, at varius magna rhoncus sed. Vivamus a odio urna, iaculis dignissim lectus. Integer aliquam felis eu sapien vestibulum ornare. Vivamus nec euismod sapien. Mauris quis eros ligula, sed pulvinar sem. Aenean sodales tempor malesuada. Aliquam erat volutpat. Aenean vel eros velit, et porttitor elit. Phasellus volutpat blandit quam eu fringilla. Integer ornare convallis tincidunt. Suspendisse commodo iaculis est vulputate volutpat. Donec at massa arcu. Sed sit amet commodo mauris. Aliquam erat volutpat. Integer eu augue vel erat euismod volutpat eu vel massa. Curabitur id erat vitae nisi imperdiet scelerisque id ut arcu. Quisque commodo dolor vitae erat imperdiet consectetur.</p>

   <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. In sodales justo nec mauris aliquam vitae feugiat magna congue. Morbi dignissim volutpat dui id porttitor. Donec auctor feugiat dolor, at varius magna rhoncus sed. Vivamus a odio urna, iaculis dignissim lectus. Integer aliquam felis eu sapien vestibulum ornare. Vivamus nec euismod sapien. Mauris quis eros ligula, sed pulvinar sem. Aenean sodales tempor malesuada. Aliquam erat volutpat. Aenean vel eros velit, et porttitor elit. Phasellus volutpat blandit quam eu fringilla. Integer ornare convallis tincidunt. Suspendisse commodo iaculis est vulputate volutpat. Donec at massa arcu. Sed sit amet commodo mauris. Aliquam erat volutpat. Integer eu augue vel erat euismod volutpat eu vel massa. Curabitur id erat vitae nisi imperdiet scelerisque id ut arcu. Quisque commodo dolor vitae erat imperdiet consectetur.</p>

 </div>

</div>

以及以下CSS:

#wrap {width: 70%;
 margin: 1em auto;
 overflow: hidden;
 overflow-x: visible;
 }

#content
 {width: 90%;
 margin: 0 auto;
 -moz-box-shadow: 0 0 1em #ccc;
 -webkit-box-shadow: 0 0 1em #ccc;
 }

#content p
 {overflow-y: hidden;
 padding: 0.5em 0;
 }

(现场演示位于此处:http://davidrhysthomas.co.uk/so/shadows.html。)

<p>如果您向包含的元素(尤其是元素,这就是我使用它的原因)添加边距,那么脆弱性就会蔓延padding。但是,几乎可以将-moz-box-shadow(and/or -webkit-box-shadow) 应用于#contentdiv,并使用#wrapdiv 来剪辑阴影,overflow-y: hidden;当然,由于尊重overflow-y.

另一方面,解释box-shadow或多或少的浏览器肯定会适当地处理overflow-y.

于 2010-03-02T02:03:39.790 回答
4

这样做的方法是将带有阴影的框放在溢出设置为“隐藏”的 div 下。例如,要围绕仅出现在左侧、顶部和右侧的框创建阴影:

CSS:

#container {
    height: 101px;
    overflow: hidden;
    padding: 5px 5px 0;
    width: 105px;
}
#shadow-box {
   border:1px solid #aaa;
   width:100px;
   height:100px;
   box-shadow:0 0 4px 1px #666;
}

HTML:

<div id="container">
   <div id="shadow-box"></div>
<div>

展示:

在此处输入图像描述

您可以调整#container 填充和大小以根据您的需要进行剪辑。在这个例子中,我剪裁了#shadow-box 的底部边框。

于 2012-10-21T03:55:33.567 回答
1

正如我在我的一个相关问题中所说,这个问题的解决方案要么非常模糊,要么用当前的技术是不可能的。它真的太糟糕了,因为它是网页设计中的一个常见主题,所以没有办法做到这一点。

我求助于使用 png 阴影,因为它似乎是唯一理智的解决方案。

感谢您的所有建议。

于 2010-05-13T02:52:28.310 回答
1

如果为目标元素及其相邻元素设置 z-index,则可以防止边缘出现阴影/模糊。在您不想要阴影/模糊的边缘上,通过 z-index 属性将相邻元素放置在更高的平面上。例如,如果您有一个带有盒子阴影的侧边导航"box-shadow: 6px 0px 10px #bdbdbd",那么 box-shadow 属性将导致顶部边缘(到标题)上出现一些出血。您可以通过将标题上的 z-index 属性设置为高于 nav 元素的 z-index 的值来防止 box-shadow 属性的模糊溢出到标题元素上。您需要将 header 和 nav 元素的位置都设置为“相对”,否则 z-index 将不起作用(z-index 不适用于默认位置“static”)。

我为标题的 z-index 随机选择了值 10,为导航元素的 z-index 选择了 9。这会将标题放置在导航元素的顶部,您将不会在该边缘看到阴影/模糊。

#header {
    background-color: #1c2a48;
    display: flex;
    position: relative;
    z-index: 10;
    width: 100%;
}
#nav {
    display: flex;
    float: left;
    position: relative;
    z-index: 9;
    height: calc(100vh - 44.6px) !important;
    width: 187px;
    border-right: .5px solid rgba(180,180,180,0.7);
    background-color: #fafafa;
    box-shadow: 6px 0px 10px #bdbdbd;
}
于 2020-07-28T02:03:04.037 回答
0

我认为总是可能会有一点渗出到相邻的边,随着模糊值的增加会变得更加明显。您可以通过在希望阴影出现的侧面使用低模糊和更高的偏移来抵消感知的渗透。例如,这会在侧面产生明显的阴影,在顶部和底部产生几乎不可见的阴影:

box-shadow: #888 3px 0px 2px, #888 -3px 0px 2px;
于 2010-03-02T02:03:12.757 回答
0

基于迈克尔斯spread-offset解决方案非常好。问题在于盒子阴影没有跑到边缘,这可能正是大多数人希望阴影看起来的样子。

下面是基于我clip-path的方法,它不仅可以让你用力切割阴影,还可以更好地控制阴影应该出现在哪一侧。这里是正常、扩展偏移和剪辑路径之间的比较:

.container {
  padding: 65px 0px;
  text-align: center;
}

.box {
  display: inline-block;
  width: 50px;
  height: 50px;
  text-align: center;
  line-height: 50px;
  background: #0f0;
  margin: 15px;
}

/* default box shadow */
.box1 { 
  box-shadow: 0px 0px 10px 5px #000;
}

/* single side with spread-offset */
.box2 {
  box-shadow: 0px 10px 5px -5px rgba(0,0,0,.8);
}

/* single side with clip-path */
.box3 {
  box-shadow: 0px 0px 10px 5px #000;
  clip-path: polygon(0 0, 100% 0, 100% 300%, 0 300%);
}
    <div class="container">

      <div class="box box1">1</div>
      
      <div class="box box2">2</div>
      
      <div class="box box3">3</div>

    </div>

浏览器对剪辑路径的支持相当不错。这是用于创建剪辑路径蒙版的一个不错的小工具

于 2021-01-05T09:22:35.950 回答