Creando una caja de sombra CSS3 en todos los lados menos uno

115

Tengo una barra de navegación con pestañas donde me gustaría que la pestaña abierta tenga una sombra para diferenciarla de las otras pestañas. También me gustaría que toda la sección de pestañas tenga una sola sombra (ver la línea horizontal inferior) subiendo, sombreando la parte inferior de todas las pestañas excepto la abierta.

Voy a usar la box-shadowpropiedad de CSS3 para hacerlo, pero no puedo encontrar una manera de sombrear solo las partes que quiero.

Normalmente cubriría la sombra inferior de la pestaña abierta con el área de contenido (más alta z-index), pero en este caso el área de contenido en sí tiene una sombra, por lo que terminaría cubriendo la pestaña.

Diseño de pestaña

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

Línea de sombra.

La sombra iría hacia arriba desde las líneas horizontales y hacia afuera de las líneas verticales.

                _______
               | |
_______________ | | _________________

Aquí hay un ejemplo en vivo:

¿Alguna ayuda, genios?

bloudermilk
fuente
23
@the_drow Re: CSS3, me gusta considerar las características de diseño como sombras paralelas, esquinas redondeadas, etc. una recompensa para aquellos usuarios que usan navegadores modernos.
bloudermilk
3
WOW, esto es exactamente lo que necesitaba, me alegro de que ya exista una pregunta. Yo también quiero aplicar esto a una pestaña exactamente como la mostraste, wow wow wow: D
Jorge Israel Peña
Otra excelente manera de resolver este problema es usar pseudo elementos, consulte mi respuesta para obtener más detalles.
Silver Ringvee
Vea los detalles de la solución de pseudo-elemento aquí: stackoverflow.com/a/38372215/4769218
Silver Ringvee
Sé que esta es una pregunta antigua, pero ¿se conoce el tamaño de las pestañas? ¿O son flexibles? Puedo imaginar que se podría establecer la altura, pero no el ancho.
Luke

Respuestas:

72

En su muestra, cree un div dentro de #content con este estilo

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

y cambie el estilo de #content (elimine los rellenos) y agregue sombra

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

agregar sombras a las pestañas:

#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 */
}
Pedro
fuente
Falta algo en esta solución. Editando su código y aplicando los estilos recomendados, todavía terminas con una sombra sobre la pestaña 'seleccionada'. Parece que hay un desbordamiento: ¿falta oculta?
Bob Spryn
1
Sí. Necesitaría un desbordamiento: oculto en la navegación para que funcione.
Bob Spryn
1
La 'sombra de línea' que se muestra en #content_over_shadowdebería tener #contentel estilo de en.
AppleGrew
Bueno, esta solución podría ser correcta en 2009, pero ahora no lo es. La respuesta correcta es stackoverflow.com/a/9800481/835753
Guilherme Ferreira
Una solución con pseudo elemento: stackoverflow.com/a/38372215/4769218
Silver Ringvee
25

Córtelo con desbordamiento.

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>

Kornel
fuente
3
Aquí también hay un ejemplo de cómo cortarlo con overflow starikovs.com/2011/11/09/css3-one-side-shadow .
starikovs
Este método solo funcionará cuando sea el lado inferior en el que no desee la sombra
andrhamm
¡Funciona genial! El div padre se puede colocar en el correctoz-index
Rvanlaak
Actualmente estoy usando esta solución. Estoy teniendo algunos problemas con el elemento secundario que debe desbordarse (como el botón Me gusta de Facebook).
Loenix
1
No es muy útil para la mayoría de los diseños receptivos, ya que debe establecer la altura de los elementos
Jonathan Tonge
13

Puede usar múltiples sombras CSS sin ningún otro div para obtener el efecto deseado, con la advertencia de que no hay sombras en las esquinas.

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>

En general, aunque es muy discreto.

Danny C
fuente
1
Esta sería una gran solución, pero como dices, las esquinas están torcidas. jsfiddle.net/mahemoff/ZStTr
mahemoff
1
Funcionó como un encanto para mis necesidades de sombra insertada con esquinas redondeadas. ¡Gracias!
Bruno Ely
9

Una forma más, bastante creativa, de resolver este problema es agregar: after o: before pseudo elemento a uno de los elementos. En mi caso se ve así:

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

Vea la captura de pantalla, hizo que el pseudo elemento sea rojo para hacerlo más visible.

Vea la captura de pantalla, hizo que el pseudo elemento sea rojo para hacerlo más visible.

Ringvee de plata
fuente
7

Personalmente me gusta más la solución que se encuentra aquí: http://css3pie.com/demos/tabs/

Le permite tener un estado cero o un estado de desplazamiento con un color de fondo que aún tiene la sombra del contenido a continuación superpuesto. No estoy seguro de que sea posible con el método anterior:

pestaña sombreada con estado de desplazamiento

ACTUALIZAR:

De hecho, estaba equivocado. Puede hacer que la solución aceptada admita el estado de desplazamiento que se muestra arriba. Hacer esto:

En lugar de tener el relativo positivo en la a, colóquelo en la clase a.active con un índice z que sea más alto que su div #content a continuación (que tiene la sombra) pero es más bajo que el índice z en su content_wrapper.

Por ejemplo:

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

luego con tu 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 */
Bob Spryn
fuente
7

Actualizar:

clip-path ahora es compatible con los principales navegadores.


Respuesta original:

Si está dispuesto a utilizar tecnología experimental con solo un apoyo parcial , puede utilizar la clip-pathpropiedad .

Esto producirá el efecto deseado: una sombra de caja en los lados superior, izquierdo y derecho con un corte limpio en el borde inferior.

En su caso, usaría clip-path: inset (px px px px); donde los valores de los píxeles se calculan a partir del borde en cuestión (ver más abajo).

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

Esto recortará el div en cuestión en:

  • 8 píxeles por encima de la parte superior (para incluir la sombra)
  • 8 píxeles fuera del borde derecho (para incluir la sombra)
  • 0 píxeles desde la parte inferior (para ocultar la sombra)
  • 8 píxeles fuera del borde izquierdo (para incluir la sombra)

Tenga en cuenta que no se requieren comas entre los valores de los píxeles.

El tamaño del div puede ser flexible.

Luke
fuente
Desafortunadamente, hay un espacio donde las dos sombras se superponen.
sbaechler
@sbaechler, ¿puedes darnos más detalles? ¿Dónde se superponen las sombras?
Luke
4

también puede cubrir la sombra utilizando varias sombras de caja.

sombra de cuadro: 0 10px 0 #fff, 0 0 10px #ccc;

usuario2090657
fuente
1

Si agregó dos tramos para enganchar, podría usar dos, algo como:

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

en un tramo y

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

en otro. ¡Podría funcionar!

Si las sombras se superponen, incluso podría usar 3 sombras: una 1px a la izquierda, una 1px a la derecha y una 1px hacia arriba, o el grosor que desee.

Rich Bradshaw
fuente
0

Hice una especie de truco, no perfecto, pero se ve bien:

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