Créer une boîte-ombre CSS3 de tous les côtés sauf un

115

J'ai une barre de navigation à onglets dans laquelle j'aimerais que l'onglet ouvert ait une ombre pour le distinguer des autres onglets. J'aimerais également que toute la section des onglets ait une seule ombre (voir la ligne horizontale du bas) qui monte, ombrageant le bas de tous les onglets à l'exception de celui ouvert.

Je vais utiliser la box-shadowpropriété de CSS3 pour le faire, mais je ne peux pas trouver un moyen d'ombrer uniquement les parties que je veux.

Normalement, je couvrirais l'ombre inférieure de l'onglet ouvert avec la zone de contenu (plus haut z-index), mais dans ce cas, la zone de contenu elle-même a une ombre, ce qui finirait par couvrir l'onglet.

Disposition des onglets

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

Ligne d'ombre.

L'ombre remonterait à partir des lignes horizontales et à l'extérieur des lignes verticales.

                _______
               | |
_______________ | | _________________

Voici un exemple en direct:

Avez-vous de l'aide là-bas, génies?

lait de bloud
la source
23
@the_drow Re: CSS3, j'aime considérer les fonctionnalités de conception comme les ombres portées, les coins arrondis, etc. comme une récompense pour les utilisateurs qui utilisent des navigateurs modernes.
bloudermilk
3
WOW c'est exactement ce dont j'avais besoin, heureux qu'une question existe déjà. Moi aussi je veux appliquer cela à un onglet exactement comme vous l'avez montré, wow wow wow: D
Jorge Israel Peña
Un autre excellent moyen de résoudre ce problème consiste à utiliser des pseudo éléments, voir ma réponse pour plus de détails.
Silver Ringvee le
Voir les détails de la solution de pseudo-élément ici: stackoverflow.com/a/38372215/4769218
Silver Ringvee
Je sais que c'est une vieille question, mais la taille des onglets est-elle connue? Ou sont-ils flexibles? Je peux imaginer que la hauteur pourrait être définie, mais pas la largeur?
Luke

Réponses:

72

Dans votre exemple, créez un div dans #content avec ce style

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

et changez le style #content (supprimez les rembourrages) et ajoutez une ombre

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

ajouter des ombres aux onglets:

#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 */
}
Peter
la source
Il manque quelque chose à cette solution. En éditant son code et en appliquant les styles recommandés, vous vous retrouvez toujours avec une ombre sur l'onglet «sélectionné». On dirait qu'il y a un débordement: caché manquant?
Bob Spryn
1
Oui. Vous auriez besoin d'un débordement: caché sur la navigation pour le faire fonctionner.
Bob Spryn
1
L '«ombre de ligne» affichée dans #content_over_shadowdevrait en fait être dans #contentle style de.
AppleGrew
Eh bien cette solution mabe était correcte en 2009, mais maintenant elle ne l'est pas. La bonne réponse est stackoverflow.com/a/9800481/835753
Guilherme Ferreira
Une solution avec pseudo élément: stackoverflow.com/a/38372215/4769218
Silver Ringvee
25

Coupez-le avec trop-plein.

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
la source
3
Voici également un exemple de coupure avec le débordement starikovs.com/2011/11/09/css3-one-side-shadow .
starikovs
Cette méthode ne fonctionnera que si vous ne voulez pas que l'ombre soit sur le côté inférieur
andrhamm
Fonctionne très bien! Le div parent peut être placé sur le bonz-index
Rvanlaak
J'utilise actuellement cette solution, j'obtiens des problèmes avec l'élément enfant qui doit déborder (comme le bouton facebook).
Loenix
1
Pas très utile pour les designs les plus réactifs car il faut régler la hauteur des éléments
Jonathan Tonge
13

Vous pouvez utiliser plusieurs ombres CSS sans autres divs pour obtenir l'effet souhaité, avec la mise en garde de l'absence d'ombres dans les coins.

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>

Dans l'ensemble, c'est très discret.

Danny C
la source
1
Ce serait une excellente solution, mais comme vous le dites, les coins sont bancaux. jsfiddle.net/mahemoff/ZStTr
mahemoff
1
A fonctionné comme un charme pour mes besoins d'ombre en médaillon avec des coins arrondis. Merci!
Bruno Ely
9

Une autre façon, plutôt créative, de résoudre ce problème est d'ajouter: après ou: avant un pseudo élément à l'un des éléments. Dans mon cas, cela ressemble à ceci:

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

Voir la capture d'écran, rendre le pseudo élément rouge pour le rendre plus visible.

Voir la capture d'écran, rendre le pseudo élément rouge pour le rendre plus visible.

Ringvee en argent
la source
7

Personnellement, j'aime le mieux la solution trouvée ici: http://css3pie.com/demos/tabs/

Il vous permet d'avoir un état zéro ou un état de survol avec une couleur d'arrière-plan qui a toujours l'ombre du contenu ci-dessous qui la superpose. Pas sûr que ce soit possible avec la méthode ci-dessus:

onglet ombré avec état de survol

METTRE À JOUR:

En fait, j'avais tort. Vous pouvez faire en sorte que la solution acceptée prenne en charge l'état de survol indiqué ci-dessus. Faites ceci:

Au lieu d'avoir le relatif positif sur le a, placez-le sur la classe a.active avec un z-index supérieur à votre #content div ci-dessous (qui a l'ombre dessus) mais inférieur au z-index de votre content_wrapper.

Par exemple:

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

puis avec votre 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
la source
7

Mettre à jour:

clip-path est désormais pris en charge dans tous les principaux navigateurs.


Réponse originale:

Si vous souhaitez utiliser une technologie expérimentale avec un support partiel seulement , vous pouvez utiliser la clip-pathpropriété .

Cela produira l'effet désiré: une ombre de boîte sur les côtés supérieur, gauche et droit avec une coupure nette sur le bord inférieur.

Dans votre cas, vous utiliseriez clip-path: inset (px px px px); où les valeurs de pixel sont calculées à partir du bord en question (voir ci-dessous).

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

Cela va couper le div en question à:

  • 8 pixels au-dessus du haut (pour inclure l'ombre)
  • 8 pixels à l'extérieur du bord droit (pour inclure l'ombre)
  • 0 pixels du bas (pour masquer l'ombre)
  • 8 pixels à l'extérieur du bord gauche (pour inclure l'ombre)

Notez qu'aucune virgule n'est requise entre les valeurs de pixel.

La taille du div peut être flexible.

Luke
la source
Malheureusement, il y a un espace où les deux ombres se chevauchent.
sbaechler
@sbaechler pouvez-vous élaborer? Où les ombres se chevauchent-elles?
Luc
4

vous pouvez également couvrir l'ombre en utilisant plusieurs ombres de boîte.

boîte-ombre: 0 10px 0 #fff, 0 0 10px #ccc;

user2090657
la source
1

Si vous avez ajouté deux travées à accrocher, vous pouvez en utiliser deux, quelque chose comme:

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

sur une travée et

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

sur un autre. Pourrait fonctionner!

Si les ombres se chevauchent, vous pouvez même utiliser 3 ombres - une 1px à gauche, une 1px à droite et une 1px vers le haut, ou quelle que soit l'épaisseur souhaitée.

Rich Bradshaw
la source
0

J'ai fait une sorte de hack, pas parfait, mais ça a l'air 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);
}
user2162298
la source