Создание тени блока CSS3 со всех сторон, кроме одной


115

У меня есть панель навигации с вкладками, где я бы хотел, чтобы открытая вкладка имела тень, чтобы отделить ее от других вкладок. Я также хотел бы, чтобы у всего раздела вкладок была одна тень (см. Нижняя горизонтальная линия), поднимающаяся вверх, затеняя нижнюю часть всех вкладок, кроме открытой.

Я собираюсь использовать для этого box-shadowсвойство CSS3 , но я не могу придумать способ затенять только те части, которые мне нужны.

Обычно я бы закрывал нижнюю тень открытой вкладки областью содержимого (выше z-index), но в этом случае сама область содержимого имеет тень, так что она просто закрывает вкладку.

Макет вкладки

     _______ _______ _______
    | | | | | |
____ | _______ | __ | | __ | _______ | ______

Линия тени.

Тень поднималась бы вверх от горизонтальных линий и наружу от вертикальных линий.

                _______
               | |
_______________ | | _________________

Вот живой пример:

Есть какая-нибудь помощь, гении?


23
@the_drow Re: CSS3, мне нравится рассматривать такие особенности дизайна, как тени, закругленные углы и т. д., как награду для тех пользователей, которые используют современные браузеры.
bloudermilk

3
Ничего себе, это именно то, что мне нужно, рад, что вопрос уже существует. Я тоже хочу применить это к вкладке точно так же, как вы показали, вау, вау, вау: D
Хорхе Исраэль Пенья

Еще один отличный способ решить эту проблему - использовать псевдоэлементы, подробнее см. Мой ответ.
Silver Ringvee

См. Подробности о решении
псевдоэлементов

Я знаю, что это старый вопрос, но известен ли размер вкладок? Или они гибкие? Я могу представить, что высота может быть установлена, но не ширина?
Люк,

Ответы:


72

В вашем примере создайте div внутри #content с этим стилем

#content_over_shadow {
    padding: 1em;
    position: relative; /* look at this */
    background:#fff;    /* a solid background (non transparent) */
}

и измените стиль #content (удалите отступы) и добавьте тень

#content {
    font-size: 1.8em;
    box-shadow: 0 0 8px 2px #888; /* line shadow */
}

добавить тени на вкладки:

#nav li a {
    margin-left: 20px;
    padding: .7em .5em .5em .5em;
    font-size: 1.3em;
    color: #FFF;
    display: inline-block;
    text-transform: uppercase;
    position: relative;
    box-shadow: 0 0 8px 2px #888; /* the shadow */
}

В этом решении чего-то не хватает. Редактируя его код и применяя рекомендованные стили, вы все равно получаете тень над «выбранной» вкладкой. Кажется, переполнение: скрыто отсутствует?
Боб Сприн

1
Ага. Вам понадобится overflow: hidden на навигационной панели, чтобы она работала.
Боб Сприн

1
Показанная «линия тени» #content_over_shadowдолжна соответствовать #contentстилю пользователя.
AppleGrew

Ну, это решение было правильным в 2009 году, но сейчас это не так. Правильный ответ: stackoverflow.com/a/9800481/835753
Гильерме Феррейра

Решение с
псевдоэлементом

25

Срезать с переливом.

div div {box-shadow:0 0 5px #000; height:20px}
div {overflow:hidden;height:25px; padding:5px 5px 0 5px}
<div><div>tab</div></div>


3
Вот еще пример с обрезкой переполнения starikovs.com/2011/11/09/css3-one-side-shadow .
starikovs 09

Этот метод будет работать только тогда, когда вы не хотите, чтобы тень была на нижней стороне
andrhamm

Прекрасно работает! Родительский div можно разместить правильноz-index
Рванлаак

В настоящее время я использую это решение, у меня возникают проблемы с дочерним элементом, который необходимо переполнить (как кнопка facebook).
Loenix

1
Не очень полезно для большинства адаптивных дизайнов, поскольку вам нужно устанавливать высоту элементов
Джонатан Тонг

13

Вы можете использовать несколько теней CSS без каких-либо других div, чтобы получить желаемый эффект, с предостережением об отсутствии теней по углам.

div.shadow {
    -webkit-box-shadow: 0 -3px 3px -3px black, 3px 0px 3px -3px black, -3px 0px 3px -3px black;
    -moz-box-shadow:    0 -3px 3px -3px black, 3px 0px 3px -3px black, -3px 0px 3px -3px black;
    box-shadow:         0 -3px 3px -3px black, 3px 0px 3px -3px black, -3px 0px 3px -3px black;
    height: 25px
}
 <div style="height: 25px"><div class="shadow">tab</div></div>

В целом, хотя это очень ненавязчиво.


1
Это было бы отличным решением, но, как вы говорите, углы шаткие. jsfiddle.net/mahemoff/ZStTr
mahemoff

1
Сработало как шарм для моих теневых вставок с закругленными углами. Спасибо!
Бруно Эли

9

Еще один, довольно креативный способ решения этой проблемы - это добавление псевдоэлемента: after или: before к одному из элементов. В моем случае это выглядит так:

#magik_megamenu>li:hover>a:after {
    height: 5px;
    width: 100%;
    background: white;
    content: '';
    position: absolute;
    bottom: -3px;
    left: 0;
}

Посмотрите на снимок экрана, псевдоэлемент сделан красным, чтобы он был более заметным.

Посмотрите на снимок экрана, псевдоэлемент сделан красным, чтобы он был более заметным.


7

Лично мне больше всего нравится найденное здесь решение: http://css3pie.com/demos/tabs/

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

затененная вкладка с состоянием наведения

ОБНОВИТЬ:

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

Вместо того, чтобы иметь положительный родственник для a, поместите его в класс a.active с z-index, который выше, чем ваш div #content ниже (на котором есть тень), но ниже, чем z-index на вашем content_wrapper.

Например:

<nav class="ppMod_Header clearfix">
    <h1 class="ppMod_PrimaryNavigation-Logo"><a class="ppStyle_Image_Logo" href="/">My company name</a></h1>
    <ul class="ppList_PrimaryNavigation ppStyle_NoListStyle clearfix">
        <li><a href="/benefits">Benefits</a></li>
        <li><a class="ppStyle_Active" href="/features">Features</a></li>
        <li><a href="/contact">Contact</a></li>
        <li><a href="/company">Company</a></li>
    </ul>
</nav>
<div id="ppPage-Body">
    <div id="ppPage-BodyWrap">
        content goes here
    </div>
</div>

затем с вашим css:

#ppPage-Body
    box-shadow: 0 0 12px rgba(0,0,0,.75)
    position: relative /* IMPORTANT PART */

#ppPage-BodyWrap
    background: #F4F4F4
    position: relative /* IMPORTANT PART */
    z-index: 4 /* IMPORTANT PART */


.ppList_PrimaryNavigation li a:hover
    background: #656565
    -webkit-border-radius: 6px 6px 0 0
    -moz-border-radius: 6px 6px 0 0
    border-radius: 6px 6px 0 0

.ppList_PrimaryNavigation li a.ppStyle_Active
    background: #f4f4f4
    color: #222
    -webkit-border-radius: 6px 6px 0 0
    -moz-border-radius: 6px 6px 0 0
    border-radius: 6px 6px 0 0
    -webkit-box-shadow: 0 0 12px rgba(0,0,0,0.75)
    -moz-box-shadow: 0 0 12px rgba(0,0,0,0.75)
    box-shadow: 0 0 12px rgba(0,0,0,0.75)
    position: relative /* IMPORTANT PART */
    z-index: 3 /* IMPORTANT PART */

7

Обновить:

clip-path теперь поддерживается во всех основных браузерах.


Оригинальный ответ:

Если вы хотите использовать экспериментальную технологию с частичной поддержкой , вы можете использовать clip-pathсвойство .

Это произведет желаемый эффект: тень блока сверху, слева и справа с чистым обрезом по нижнему краю.

В вашем случае вы должны использовать clip-path: inset (px px px px); где значения пикселей рассчитываются от рассматриваемого края (см. ниже).

#container {
    box-shadow: 0 0 8px 2px #888;
    clip-path: inset(-8px -8px 0px -8px);
}

Это приведет к обрезанию рассматриваемого div по адресу:

  • 8 пикселей над верхом (чтобы включить тень)
  • 8 пикселей за пределами правого края (чтобы включить тень)
  • 0 пикселей снизу (чтобы скрыть тень)
  • 8 пикселей за пределами левого края (чтобы включить тень)

Обратите внимание, что между значениями пикселей не требуется запятых.

Размер div может быть гибким.


К сожалению, есть разрыв, где две тени перекрываются.
sbaechler

@sbaechler, можешь уточнить? Где перекрываются тени?
Лука

4

вы также можете скрыть тень, используя несколько прямоугольных теней.

box-shadow: 0 10px 0 #fff, 0 0 10px #ccc;


1

Если вы добавили два пролета для подключения, вы могли бы использовать два, например:

box-shadow: -1px -1px 1px #000;

на один пролет и

box-shadow: 1px -1px 1px #000;

по другому. Может работать!

Если тени накладываются друг на друга, вы можете даже использовать 3 тени - одну на 1 пиксель влево, одну на 1 пиксель вправо и одну на 1 пиксель вверх или любой другой толщины, которую вы хотите.


0

Я сделал что-то вроде хака, не идеально, но вроде нормально:

<ul class="tabs">
<li class="tab active"> Tab 1 </li>
<li class="tab"> Tab 2 </li>
<li class="tab"> Tab 3 </li>
</ul>

<div class="tab-content">Content of tab goes here</div>

SCSS

 .tabs { list-style-type: none; display:flex;align-items: flex-end;
  .tab {
    margin: 0;
    padding: 4px 12px;
    border: 1px solid $vivosBorderGrey2;
    background-color:$vivosBorderGrey2;
    color: $vivosWhite;
    border-top-right-radius: 8px;
    border-top-left-radius: 8px;
    border-bottom: 0;
    margin-right: 2px;
    font-size: 14px;
    outline: none;
    cursor: pointer;
    transition: 0.2s;
    &.active {
      padding-bottom: 10px;
      background-color: #ffffff;
      border-color: #eee;
      color: $vivosMedGrey;
      border-bottom-color: transparent;
      box-shadow: 0px -3px 8px -3px rgba(0, 0, 0, 0.1);
    }
    &:hover {padding-bottom: 10px;
    }
   } 

.tabContent {
  border: 1px solid #eee;
  padding:10px;
  margin-top: -1px;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.