Creating a CSS3 box-shadow on all sides but one

HtmlCssShadow

Html Problem Overview


I've got a tabbed navigation bar where I'd like the open tab to have a shadow to set it apart from the other tabs. I'd also like the whole tab section to have a single shadow (see bottom horizontal line) going up, shading the bottom of all tabs except for the open one.

I'm going to use CSS3's box-shadow property to do it, but I can't figure out a way to shade only the parts I want.

Normally I'd cover up the bottom shadow of the open tab with the content area (higher z-index), but in this case the content area itself has a shadow so that would just wind up covering the tab.

Tab layout

_______    _______    _______
|       |  |       |  |       |
|||       |__||

Shadow line.

Shadow would go up from the horizontal lines, and outward of the vertical lines.

_______
|       |
|       |__

Here is a live example:

Any help out there, geniuses?

Html Solutions


Solution 1 - Html

In your sample create a div inside #content with this style

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

and change #content style (remove paddings) and add shadow

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

add shadows to tabs:

#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 */
}

Solution 2 - Html

Cut it off with overflow.

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>

Solution 3 - Html

You can use multiple CSS shadows without any other divs to get desired effect, with the caveat of of no shadows around the corners.

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>

Overall though its very unintrusive.

Solution 4 - Html

One more, rather creative, way of solving this problem is adding :after or :before pseudo element to one of the elements. In my case it looks like this:

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

See the screenshot, made the pseudo element red to make it more visible.

See the screenshot, made the pseudo element red to make it more visible.

Solution 5 - Html

Update:

clip-path is now (2020) supported in all major browsers.


Original Answer:

If you are willing to use experimental technology with only partial support, you could use the clip-path property.

This will produce the desired effect: a box shadow on the top, left and right sides with a clean cut-off on the bottom edge.

In your case you would use clip-path: inset(px px px px); where the pixel values are calculated from the edge in question (see below).

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

This will clip the div in question at:

  • 8 pixels above the top (to include the shadow)
  • 8 pixels outside of the right edge (to include the shadow)
  • 0 pixels from the bottom (to hide the shadow)
  • 8 pixels outside of the left edge (to include the shadow)

Note that no commas are required between pixel values.

The size of the div can be flexible.

Solution 6 - Html

Personally I like the solution found here best: http://css3pie.com/demos/tabs/

It allows you to have a zero state or a hover state with a background color that still has the shadow from the content below overlaying it. Not sure that's possible with the method above:

shadowed tab with hover state

UPDATE:

Actually I was incorrect. You can make the accepted solution support the hover state shown above. Do this:

Instead of having the positive relative on the a, put it on the a.active class with a z-index that is higher than your #content div below (which has the shadow on it) but is lower than the z-index on your content_wrapper.

For example:

<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>

then with your 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
    border-radius: 6px 6px 0 0

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

Solution 7 - Html

you can cover up shadow using multiple box shadows as well.

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

Solution 8 - Html

If you added two spans to hook onto then you could use two, something like:

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

on one span and

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

on another. Might work!

If the shadows overlap you could even use 3 shadows - one 1px to the left, one 1px to the right and one 1px up, or however thick you want them.

Solution 9 - Html

I did a sort of hack, not perfect, but it looks okay:

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionbloudermilkView Question on Stackoverflow
Solution 1 - HtmlPeterView Answer on Stackoverflow
Solution 2 - HtmlKornelView Answer on Stackoverflow
Solution 3 - HtmlDanny CView Answer on Stackoverflow
Solution 4 - HtmlSilver RingveeView Answer on Stackoverflow
Solution 5 - HtmlLukeView Answer on Stackoverflow
Solution 6 - HtmlBob SprynView Answer on Stackoverflow
Solution 7 - Htmluser2090657View Answer on Stackoverflow
Solution 8 - HtmlRich BradshawView Answer on Stackoverflow
Solution 9 - Htmluser2162298View Answer on Stackoverflow