Предотвратить отображение тени на определенной стороне - PullRequest
36 голосов
/ 02 марта 2010

Есть ли способ создать поле-тень css, в котором независимо от значения размытия тень появляется только на желаемых сторонах?

Например, если я хочу создать 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;}

Ответы [ 7 ]

44 голосов
/ 02 мая 2011

Существует четвертое расстояние, которое вы можете определить, называемое смещением спреда, которое перемещает тень внутрь или наружу со всех четырех сторон. Таким образом, если вы установите его как отрицательное значение расстояния размытия, это сместит тень внутрь на то же расстояние, что и размытие расширяет тень наружу, эффективно скрывая ее. Конечно, это также сместит тень внутрь на той стороне, где вы хотите, чтобы она появилась, поэтому вам нужно увеличить смещение на расстояние размытия, чтобы отменить это. т.е.

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);
7 голосов
/ 29 мая 2011

Вы также можете использовать клип: прямоугольник (0px, 210px, 200px, -10px);

К сожалению, мне так и не удалось найти способ заставить его работать с коробкой гибкого размера.

Я часто использую это для выпадающих меню, где мне нужны тени только по бокам и снизу. В этом случае я просто установил для правого и нижнего значения клипа какое-то старшее число, например

клип: прямоугольник (0px, 1000px, 1000px, -10px); / * Обрезать верхнюю часть коробки-тень от * /

#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;
}
6 голосов
/ 02 марта 2010

Да, но он довольно хрупкий.

Использование следующего 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 (и / или -webkit-box-shadow) к #content div и используйте #wrap div для обрезки тени, используя overflow-y: hidden;, что, конечно, делает его еще хрупкий из-за количества браузеров, которые уважают overflow-y.

С другой стороны, браузеры, которые интерпретируют box-shadow, более или менее определенно работают с overflow-y.

4 голосов
/ 21 октября 2012

Способ сделать это - поместить коробку с тенью под 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>

Дисплей:

enter image description here

Вы можете настроить заполнение #container и его размер в соответствии с вашими потребностями. В этом примере я обрезаю нижнюю границу # shadow-box.

2 голосов
/ 16 декабря 2016

У меня есть 2 возможных решения, которые дают точно желаемый эффект: "нормальная" тень от блока на некоторых краях и ничего на других. Многие из решений, перечисленных в этом и других С.О. вопросы приводят к теням, которые «рассеиваются» по мере приближения к краю, где не должно быть тени, тогда как на самом деле я полагаю, что большинство людей хотят чистого отсечения.

Однако оба решения поставлены с оговорками.


Решение 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);
}

Выше будет обрезать верхнюю и нижнюю рамки-тени, оставляя 5-пиксельные левую и правую рамки-тени. Обратите внимание, что размер div должен быть известен.

Если размер div неизвестен, этот метод будет работать только для обрезки верхней и левой теней , используя что-то вроде clip: rect(0, 3000px, 3000px, 0); (обратите внимание на массивные значения для правого и нижнего значений, чтобы div любого размера).

1 голос
/ 13 мая 2010

Как я уже говорил в моем связанном вопросе, решение этой проблемы либо очень неясно, либо невозможно с современной технологией. Очень жаль, что это невозможно сделать, так как это общая тема в веб-дизайне.

Я прибегнул к использованию тени png, так как она кажется единственным разумным решением.

Спасибо за все ваши предложения.

0 голосов
/ 02 марта 2010

Я думаю, что всегда есть небольшая утечка к соседним сторонам, которая станет более очевидной при более высоких значениях размытия.Вы можете сместить воспринимаемое прохождение, используя низкое размытие и большее смещение по сторонам, на которых вы хотите, чтобы тень появляласьНапример, это создаст заметную тень по бокам и почти невидимую сверху и снизу:

box-shadow: #888 3px 0px 2px, #888 -3px 0px 2px;
...