web-dev-qa-db-fra.com

Pourquoi l'insert de boîte-ombre ne fonctionne pas sur les images?

J'ai un conteneur qui utilise l'ombre de la boîte d'encart. Le conteneur contient des images et du texte. L'ombre incrustée ne fonctionne apparemment pas sur les images:

The problem

La section blanche ici est le conteneur. Il contient une image blanche et une ombre encadrée lui est appliquée.

<main>
    <img src="whiteimage.png">
</main>
body {
    background-color: #000000;
}

main {
    position: absolute;
    bottom: 0;
    right: 0;
    width: 90%;
    height: 90%;
    background-color: #FFFFFF;
    box-shadow: inset 3px 3px 10px 0 #000000;
}

Existe-t-il un moyen de faire en sorte que l'ombre de la boîte d'insertion chevauche les images?

Démo en direct

39
FalconC

Étant donné que l'ombre fait partie du conteneur parent, elle est affichée sous l'image. Une alternative est d'avoir un div qui place une ombre sur l'image comme ceci:

<main>
    <img src="https://upload.wikimedia.org/wikipedia/commons/d/d2/Solid_white.png" />
    <div class="shadow"></div>
</main>

CSS: 

.shadow {
    position: absolute;
    width: 100%;
    height: 100%;
    box-shadow: inset 3px 3px 10px 0 #000000;
    border-radius: 20px;
    top: 0;
    left: 0;
}

Edit: J'ai mis à jour le violon pour inclure le rayon de la bordure sur l'ombre et sur l'image qui résout le problème identifié dans les commentaires.

https://jsfiddle.net/WymFE/3/

41
RyanS

Juste pour ajouter quelque chose, parce que je venais de créer quelque chose de similaire ...

Je déteste polluer mon balisage avec des éléments supplémentaires pour des raisons de style, la solution CSS consiste donc à utiliser le pseudo élément: after

main::after
{
 box-shadow: inset 3px 3px 10px 0 #000000;
 content: '';
 display: block;
 height: 100%;
 position: absolute;
 top: 0;
 width: 100%;
}

C'est probablement trop tard pour ce que vous avez essayé de faire, mais c'est la meilleure solution à mon avis.

32
Rillus

La raison pour laquelle il ne se chevauche pas, c'est parce que l'image est à l'intérieur du div, donc l'image est au-dessus de celle-ci. L'image est plus haute (plus proche de l'utilisateur) que la div.

Vous pouvez modifier l'image pour qu'elle utilise position: relative; z-index: -1 et que la div qui le contient utilise une bordure au lieu de définir une couleur d'arrière-plan sur le corps. Vous devrez utiliser box-sizing: border-box pour inclure la bordure dans la largeur de la div.

D&EACUTE;MO

body {
    background-color: #FFF;
}

main {
    position: absolute;
    bottom: 0;
    right: 0;
    width: 100%;
    height: 100%;
    border: 60px solid black;
    box-shadow: inset 3px 3px 10px 0 #000000;
    box-sizing: border-box;
}

img {
    z-index:-1;
    position: relative;
}
7
brouxhaha

Pour ceux qui utilisent des pseudo-éléments en position absolue et pleine taille: avant /: après, pensez à utiliser pointer-events: none sur le pseudo-élément afin que les éléments d'origine restent cliquables.

3
bencergazda

Vous pouvez définir l'image comme arrière-plan de la div à la place:

background-image:url(http://www.placehold.it/500x500)

Exemple jsFiddle

2
j08691

Si vous êtes malin avec vos décimales, une solution simple consiste à stocker votre contenu dans un fichier séparé que vous sélectionnez et implémentez un certain nombre de pixels à partir du haut. 

Par exemple, supposons que votre en-tête ait une hauteur de 50 px. Vous pouvez commencer votre identifiant div #content par 53.45px à partir du haut (ou quelle que soit la hauteur de votre ombre portée) pour afficher votre ombre au-dessus des images.

Un problème avec ceci est que si vous utilisez une ombre plutôt transparente, plus elle est transarente, plus elle peut paraître collante en implémentant ce css. 

En pratique, le code serait le suivant:

HTML:

  <header>
Whatever's in your header
</header>

<div id="content>
Page content
</div>

CSS:

header {
    height: 50px;
    box-shadow: 0 5px 5px rgba(0,0,0,1);
}

#content {
    top: 55px;
}
1
James Lewis

Comme Rilus l'a mentionné, nous pourrions utiliser une pseudo classe. Malheureusement, cela ne semble pas fonctionner sur une étiquette img pour une raison quelconque, mais nous pouvons utiliser une combinaison de conteneurs intérieurs et extérieurs pour obtenir l'effet recherché.

.outer:hover .inner:after {
position: absolute;
content: '';
color: white;
display:block;
bottom: -0px;
right: -0px;
width: 100%;
height: 100%;
z-index: 11;
border: solid 10px red;
}

http://jsbin.com/kabiwidego/1/

je ne suis pas sûr que c’est-à-dire 10, car il semble gérer des pseudo-classes qui sont positionnées de manière légèrement différente de la plupart des navigateurs.

0
dan