Comment créer une ombre portée uniquement sur un côté d'un élément?

230

Existe-t-il un moyen de déposer l'ombre uniquement sur le fond?. J'ai un menu avec 2 images côte à côte. Je ne veux pas d'une bonne ombre car elle chevauche la bonne image. Je n'aime pas utiliser d'images pour cela, donc y a-t-il un moyen de le déposer uniquement sur le fond comme:

box-shadow-bottom: 10px #FFF; ou similaire?

-moz-box-shadow: 0px 3px 3px #000;
-webkit-box-shadow: 0px 3px 3px #000;
box-shadow-bottom: 5px #000;
/* For IE 8 */
-ms-filter: "progid:DXImageTransform.Microsoft.Shadow(Strength=4, Direction=180, Color='#000000')";
/* For IE 5.5 - 7 */
filter: progid:DXImageTransform.Microsoft.Shadow(Strength=4, Direction=180, Color='#000000');
damage000
la source
8
Vos références de réponse acceptées box-shadow-bottomqui n'existent pas et qui ne sont prises en charge par personne. Voir nicolasgallagher.com/css-drop-shadows-without-images/demo pour les techniques légères d'ombre de boîte.
Paul Irish
@Paul ... J'avais une faute de frappe, c'est fixe.
Hristo
1
Les commentaires dans votre exemple CSS sont trompeurs - filterfonctionneront également dans IE8 et IE9. Pas besoin -ms-filterdans ce cas.
Mathias Bynens
Vous pouvez adapter cette ombre css réaliste d'encart: stackoverflow.com/a/20596554/1491212
Armel Larcier

Réponses:

234

MISE À JOUR 4

Identique à la mise à jour 3 mais avec un css moderne (= moins de règles) de sorte qu'aucun positionnement spécial sur le pseudo-élément n'est requis.

#box {
    background-color: #3D6AA2;
    width: 160px;
    height: 90px;
    position: absolute;
    top: calc(10% - 10px);
    left: calc(50% - 80px);
}

.box-shadow:after {
    content:"";
    position:absolute;
    width:100%;
    bottom:1px;
    z-index:-1;
    transform:scale(.9);
    box-shadow: 0px 0px 8px 2px #000000;
}
<div id="box" class="box-shadow"></div>

MISE À JOUR 3

Toutes mes réponses précédentes utilisaient un balisage supplémentaire pour créer cet effet, ce qui n'est pas nécessairement nécessaire. Je pense que c'est une solution beaucoup plus propre ... la seule astuce consiste à jouer avec les valeurs pour obtenir le bon positionnement de l'ombre ainsi que la bonne force / opacité de l'ombre. Voici un nouveau violon, utilisant des pseudo-éléments :

http://jsfiddle.net/UnsungHero97/ARRRZ/2/

HTML

<div id="box" class="box-shadow"></div>

CSS

#box {
    background-color: #3D6AA2;
    width: 160px;
    height: 90px;
    margin-top: -45px;
    margin-left: -80px;
    position: absolute;
    top: 50%;
    left: 50%;
}

.box-shadow:after {
    content: "";
    width: 150px;
    height: 1px;
    margin-top: 88px;
    margin-left: -75px;
    display: block;
    position: absolute;
    left: 50%;
    z-index: -1;
    -webkit-box-shadow: 0px 0px 8px 2px #000000;
       -moz-box-shadow: 0px 0px 8px 2px #000000;
            box-shadow: 0px 0px 8px 2px #000000;
}

MISE À JOUR 2

Apparemment, vous pouvez le faire avec juste un paramètre supplémentaire au CSS box-shadow comme tout le monde vient de le souligner. Voici la démo:

http://jsfiddle.net/K88H9/821/

CSS

-webkit-box-shadow: 0 4px 4px -2px #000000;
   -moz-box-shadow: 0 4px 4px -2px #000000;
        box-shadow: 0 4px 4px -2px #000000;

Ce serait une meilleure solution. Le paramètre supplémentaire qui est ajouté est décrit comme suit:

La quatrième longueur est une distance étalée. Les valeurs positives entraînent l'expansion de la forme d'ombre dans toutes les directions selon le rayon spécifié. Les valeurs négatives provoquent la contraction de la forme de l'ombre.

METTRE À JOUR

Découvrez la démo sur jsFiddle: http://jsfiddle.net/K88H9/4/

Ce que j'ai fait, c'est créer un "élément d'ombre" qui se cacherait derrière l'élément réel que vous voudriez avoir une ombre. J'ai fait que la largeur de "l'élément d'ombre" soit exactement moins large que l'élément réel de 2 fois l'ombre que vous spécifiez; puis je l'ai aligné correctement.

HTML

<div id="wrapper">
    <div id="element"></div>
    <div id="shadow"></div>
</div>

CSS

#wrapper {
    width: 84px;
    position: relative;
}
#element {
    background-color: #3D668F;
    height: 54px;
    width: 100%;
    position: relative;
    z-index: 10;
}
#shadow {
    background-color: #3D668F;
    height: 8px;
    width: 80px;
    margin-left: -40px;
    position: absolute;
    bottom: 0px;
    left: 50%;
    z-index: 5;
    -webkit-box-shadow: 0px 2px 4px #000000;
       -moz-box-shadow: 0px 2px 4px #000000;
            box-shadow: 0px 2px 4px #000000;
}

Réponse originale

Oui, vous pouvez le faire avec la même syntaxe que vous avez fournie. La première valeur contrôle le positionnement horizontal et la seconde valeur contrôle le positionnement vertical. Il suffit donc de définir la première valeur sur 0pxet la seconde sur le décalage que vous souhaitez comme suit:

-webkit-box-shadow: 0px 5px #000000;
   -moz-box-shadow: 0px 5px #000000;
        box-shadow: 0px 5px #000000;

Pour plus d'informations sur les ombres de boîte, consultez celles-ci:

J'espère que ça aide.

Hristo
la source
2
Vous n'avez pas nécessairement besoin d'ajouter un div vide pour obtenir une ombre floue. Cette troisième valeur dans la déclaration: box-shadow: 0 2px 4px #000000est une valeur de flou. Voir ici http://jsfiddle.net/K88H9/7/ . Mais vous remarquerez qu'il y a un peu de flou à gauche et à droite de l'élément, alors que dans la solution de Hristo il n'y en a pas.
9
Il n'y a pas de propriété box-shadow-bottom et cet effet n'a certainement pas besoin d'un élément supplémentaire. Beurk.
Lea Verou
7
box-shadow-bottom, bien que créatif, n'existe pas réellement.
miketaylr
3
chill les gars ... c'était une faute de frappe
Hristo
1
@gryzzly ... J'ai modifié ma réponse, je n'ai pas vu ma faute de frappe tant que tout le monde ne l'a pas fait remarquer. Désolé pour ça.
Hristo
71

Utilisez simplement le paramètre spread pour réduire l'ombre:

.shadow {
  -webkit-box-shadow: 0 6px 4px -4px black;
  -moz-box-shadow: 0 6px 4px -4px black;
  box-shadow: 0 6px 4px -4px black;
}
<div class="shadow">Some content</div>

Démo en direct: http://dabblet.com/gist/a8f8ba527f5cff607327

Pour ne voir aucune ombre sur les côtés, le (valeur absolue du) rayon de diffusion (4ème paramètre) doit être le même que le rayon de flou (3ème paramètre).

Léa Verou
la source
1
cela ne fonctionne pas vraiment. à première vue, il semble que l'ombre ne soit que sur le fond, mais en fait, elle se propage toujours sur les côtés. Les exemples de tout le monde sont avec une boîte bleu assez foncé ... rendez la boîte blanche et vous verrez toute l'ombre.
Chris L
@Chris M: incrémentez simplement le paramètre spread: essayez 4 exemple avec box-shadow:0 8px 4px -6pxet vous ne verrez que l'ombre du bas!
T30
1
encore une fois, faites la boîte BLANCHE comme dans ce violon et vous verrez toujours de l'ombre tout le long des côtés et maintenant elle ne fait pas tout le chemin à travers le fond. jusqu'où êtes-vous prêt à aller sur le paramètre spread pour vous débarrasser des côtés? En outre, il est probablement préférable pour quelqu'un avec 151 représentants de ne pas modifier la réponse de quelqu'un avec 7 000 représentants. laissez-le dans un commentaire.
Chris L
1
@ T30 Bien sûr, vous pouvez éventuellement vous débarrasser des côtés en réduisant encore plus le paramètre de propagation. Mais maintenant, votre ombre n'est nulle part proche de la largeur de votre boîte. Vous avez une boîte de 84 pixels avec une ombre de 72 pixels.
Chris L
1
Réponse mise à jour. Mais fondamentalement, à moins de réduire le rayon d'étalement et d'ajuster le décalage Y, il n'y a pas grand-chose à faire. Peut-être utiliser un dégradé au lieu d'une ombre? En outre, cela ne me dérange pas que les gens modifient mes messages, mais je n'apprécie pas que les gens modifient mes messages pour ajouter des phrases écrites dans une langue semblable à Engrish. Je ne suis pas non plus un anglophone natif et je comprends les défis, mais si je modifiais le post de quelqu'un d'autre, je me sentirais suffisamment responsable pour au moins vérifier que ce que j'ai ajouté a du sens et que la grammaire n'est pas embarrassant mal.
Lea Verou
30

Si vous avez une couleur fixe à l'arrière-plan, vous pouvez masquer l'effet d'ombre latérale avec deux ombres de masquage ayant la même couleur de l'arrière-plan et flou = 0, par exemple:

box-shadow: 
    -6px 0 white,         /*Left masking shadow*/
    6px 0 white,          /*Right masking shadow*/
    0 7px 4px -3px black; /*The real (slim) shadow*/

Notez que l'ombre noire doit être la dernière et a une propagation négative (-3px) afin de l'empêcher de s'étendre au-delà des coins.

Voici le violon (changez la couleur des ombres de masquage pour voir comment ça marche vraiment ).

div{
    width: 100px;
    height: 100px;
    border: 1px solid pink;
    box-shadow: -6px 0 white, 6px 0 white, 0 7px 5px -2px black;
}
<div></div>

entrez la description de l'image ici

T30
la source
1
Serait-il préférable d'utiliser la transparentcouleur pour les ombres masquantes, non?
Angel Joseph Piscola
@AngelJosephPiscola: Astuce intelligente .. Implémenté dans la réponse, merci!
T30
@ T30 génial, mais notez qu'avec un masque transparent vous ne devriez pas avoir besoin d'un fond de couleur fixe;)
Angel Joseph Piscola
Je l'ai mieux testé et l'ombre transparente ne fonctionne pas , j'ai donc annulé les dernières modifications
T30
6

Je pense que c'est ce que vous recherchez?

.shadow {
  -webkit-box-shadow: 0 0 0 4px white, 0 6px 4px black;
  -moz-box-shadow: 0 0 0 4px white, 0 6px 4px black;
  box-shadow: 0 0 0 4px white, 0 6px 4px black;
}
<div class="shadow">wefwefwef</div>

James T
la source
2
J'adore quand les gens ne comprennent tout simplement pas. Oui, il joue avec la propagation de la première ombre (blanche) qui couvrira la marge de la vraie ombre (noir). C'est la seule manière saine d'obtenir une ombre unidirectionnelle parfaite. Particulièrement utile lorsque vous devez avoir la même ombre sur 2 parties d'un menu.
Zeno Popovici
5

Il est toujours préférable de lire les spécifications . Il n'y a pas de box-shadow-bottompropriété, et comme le souligne Lea, vous devez toujours placer la propriété non préfixée en bas, après celles préfixées.

Alors c'est:

.shadow {
  -webkit-box-shadow: 0px 2px 4px #000000;
  -moz-box-shadow: 0px 2px 4px #000000;
  box-shadow: 0px 2px 4px #000000;
}
<div class="shadow">Some content</div>

Misha Reyzlin
la source
1
Il y a de l'ombre sur les côtés
shinzou
2

Que diriez-vous d'utiliser simplement un div contenant dont le débordement est défini sur caché et un rembourrage en bas? Cela semble être la solution la plus simple.

Désolé de dire que je n'y ai pas pensé moi-même mais que je l'ai vu ailleurs .

Utiliser un élément pour envelopper l'élément en obtenant l'ombre de boîte et un débordement: caché sur le wrapper, vous pouvez faire disparaître l'ombre de boîte supplémentaire et avoir toujours une bordure utilisable. Cela résout également le problème où l'élément est plus petit qu'il n'y paraît, en raison de la propagation.

Comme ça:

#wrapper { padding-bottom: 10px; overflow: hidden; }
#elem { box-shadow: 0 0 10px black; }

Le contenu va ici

Encore une solution astucieuse quand il faut le faire en CSS pur!

Comme l'a dit Jorgen Evens .

Ben
la source
+1 pour la solution. En plus de padding-bottom(disons 5px), vous pouvez également définir un négatif margin-bottom(de -5px) pour compenser l'espace ajouté.
fabio.sang
2

Vous pouvez également utiliser clip-pathpour couper (masquer) tous les bords débordants, mais celui que vous souhaitez afficher:

.shadow {
  box-shadow: 0 4px 4px black;
  clip-path: polygon(0 0, 100% 0, 100% 200%, 0 200%);
}

Voir clip-path (MDN) . Les arguments pour polygonsont le point supérieur gauche , le point supérieur droit , le point inférieur droit et le point inférieur gauche . En définissant le bord inférieur sur 200%(ou tout nombre supérieur à 100%), vous limitez votre débordement au bord inférieur uniquement.

theengineear
la source
Donc ... en termes de base, clip-path est le débordement: propriété cachée des stéroïdes. C'est propre. ;)
Craig
1

J'avais également besoin d'une ombre, mais uniquement sous une image et je l'ai réglée légèrement à gauche et à droite. Cela a fonctionné pour moi:

.box-shadow {
   -webkit-box-shadow: 5px 35px 30px -25px #888888;
      -moz-box-shadow: 5px 35px 30px -25px #888888;
           box-shadow: 5px 35px 30px -25px #888888;
}

L'élément auquel cela est appliqué est une image à l'échelle de la page (980 px x 300 px).

Si cela aide à jouer avec les paramètres, ils s'exécutent comme suit:

ombre horizontale, ombre verticale, distance de flou, propagation (c.-à-d. taille de l'ombre) et couleur.

Chris9
la source
1

Il vaut mieux chercher l'ombre:

.header{
    -webkit-box-shadow: 0 -8px 73px 0 rgba(0,0,0,0.2);
    -moz-box-shadow: 0 -8px 73px 0 rgba(0,0,0,0.2);
    box-shadow: 0 -8px 73px 0 rgba(0,0,0,0.2);
}

ce code utilise actuellement sur stackoverflow web.

Kamlesh
la source
1

Ce stylo à code (pas par moi) montre une manière super simple de faire cela et les autres côtés par eux-mêmes assez bien:

box-shadow: 0 5px 5px -5px #333;

https://codepen.io/zeckdude/pen/oxywmm

David Daudelin
la source
0

Si votre arrière-plan est solide (ou vous pouvez le reproduire en utilisant CSS), vous pouvez utiliser le dégradé linéaire de cette façon:

div {
  background-image: linear-gradient(to top, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.3) 5px, #fff 5px, #fff 100%)
}
<div>
<p>Foobar</p>
<p>test</p>
</div>

Cela générera un dégradé de 5 pixels au bas de l'élément, du noir à 30% d'opacité au complètement transparent. Le reste de l'élément a un fond blanc. Bien sûr, en changeant les 2 derniers arrêts de couleur du dégradé linéaire, vous pouvez rendre l'arrière-plan complètement transparent.

Tibo
la source
0

Vous pouvez également faire un dégradé en bas - cela m'a été utile parce que l'ombre que je voulais était sur un élément qui était déjà semi-transparent, donc je n'avais pas à me soucier de l'écrêtage:

&:after {
      content:"";
      width:100%;
      height: 8px;
      position: absolute;
      bottom: -8px;
      left: 0;
      background: linear-gradient(to bottom, rgba(0,0,0,0.65) 0%,rgba(0,0,0,0) 100%);
    }

Faites juste correspondre les propriétés "bottom" et "height" et définissez vos valeurs rgba sur ce que vous voulez qu'elles soient en haut / en bas de l'ombre

mheavers
la source
0

Vous pouvez faire ça comme ceci:

Syntaxe générale:

selector {
   box-shadow: topBoxShadow, bottomBoxShadow, rightBoxShadow, leftBoxShadow
}

Exemple: nous voulons créer uniquement une ombre de zone inférieure de couleur rouge,

pour ce faire, nous devons définir toutes les options de côtés où nous devons définir les options d'ombre de la boîte inférieure et définir toutes les autres comme vides comme suit:

.box {
     -moz-box-shadow: 0 0 0 transparent ,0 0 10px red, 0 0 0 transparent, 0 0 0 transparent
     -o-box-shadow: 0 0 0 transparent ,0 0 10px red, 0 0 0 transparent, 0 0 0 transparent
     -webkit-box-shadow: 0 0 0 transparent ,0 0 10px red, 0 0 0 transparent, 0 0 0 transparent
     box-shadow: 0 0 0 transparent ,0 0 10px red, 0 0 0 transparent, 0 0 0 transparent
}
MUSTAPHA GHLISSI
la source
-1

mettez à jour sur quelqu'un d'autre sa réponse sur les côtés transparents au lieu du blanc afin que cela fonctionne également sur d'autres arrière-plans de couleur.

body {
  background: url(http://s1.picswalls.com/wallpapers/2016/03/29/beautiful-nature-backgrounds_042320876_304.jpg)
}

div {
  background: url(https://www.w3schools.com/w3css/img_avatar3.png) center center;
  background-size: contain;
  width: 100px;
  height: 100px;
  margin: 50px;
  border: 5px solid white;
  box-shadow: 0px 0 rgba(0, 0, 0, 0), 0px 0 rgba(0, 0, 0, 0), 0 7px 7px -5px black;
}
<div>
</div>

Jaron Koopmans
la source
-3

ombre intérieure

 .shadow {
   -webkit-box-shadow: inset 0 0 9px #000;
   -moz-box-shadow: inset 0 0 9px #000;
   box-shadow: inset 0 0 9px #000;
 }
<div class="shadow">wefwefwef</div>

Raji
la source