web-dev-qa-db-fra.com

Empêcher l'ombre de la boîte de s'afficher sur un côté spécifique

Existe-t-il un moyen de créer une ombre de boîte CSS dans laquelle, quelle que soit la valeur de flou, l'ombre n'apparaît que sur les côtés souhaités?

Par exemple, si je veux créer un div avec des ombres sur les côtés gauche et droit et aucune ombre en haut ou en bas. Le div n'est pas absolument positionné et sa hauteur est déterminée par le contenu.

-- Éditer --

@ricebowl: J'apprécie votre réponse. Peut-être pouvez-vous aider à créer une solution complète pour résoudre les problèmes énoncés dans ma réponse à votre solution ... Ma mise en page est la suivante:

<div id="container">
    <div id="header"></div>
    <div id="content"></div>
    <div id="clearfooter"></div>
</div>
<div id="footer"></div>

Et CSS comme ça:

#container {width:960px; min-height:100%; margin:0px auto -32px auto; 
       position:relative; padding:0px; background-color:#e6e6e6; 
       -moz-box-shadow: -3px 0px 5px rgba(0,0,0,.8), 
       3px 0px 5px rgba(0,0,0,.8);}
#header   {height:106px; position:relative;}
#content   {position:relative;}
#clearFooter {height:32px; clear:both; display:block; padding:0px; margin:0px;}
#footer  {height:32px; padding:0px; position:relative; width:960px; margin:0px 
           auto 0px auto;}
37
Jason Turner

Comme je l'ai indiqué dans une question connexe, la solution à ce problème est soit très obscure, soit impossible avec la technologie actuelle. C'est vraiment dommage qu'il n'y ait aucun moyen d'y parvenir car c'est un thème commun dans la conception web.

J'ai eu recours à une ombre png car elle semble être la seule solution sensée.

Merci pour toutes vos suggestions.

1
Jason Turner

Il existe une quatrième distance que vous pouvez définir, appelée décalage de propagation, qui déplace l'ombre vers l'intérieur ou vers l'extérieur sur les 4 côtés. Donc, si vous définissez cela sur le négatif de la distance de flou, cela déplacera l'ombre vers l'intérieur de la même distance que le flou étend l'ombre vers l'extérieur en la masquant efficacement. Bien sûr, cela déplacera également l'ombre vers l'intérieur du côté où vous souhaitez qu'elle apparaisse, vous devrez donc augmenter le décalage de la distance de flou pour l'annuler. c'est à dire.

box-shadow: (horizontal + blur) 0px (blur) (-blur) color;

Donc dans votre exemple:

box-shadow: -8px 0px 5px -5px rgba(0,0,0,.8), 8px 0px 5px -5px rgba(0,0,0,.8);
47
Michael

Vous pouvez également utiliser clip: rect (0px, 210px, 200px, -10px);

Malheureusement, je n'ai jamais réussi à trouver un moyen de le faire fonctionner avec une boîte de taille flexible.

Je l'utilise souvent pour les menus déroulants où je ne veux que de l'ombre sur les côtés et le bas. Dans ce cas, je viens de définir les valeurs de clip droite et inférieure à un certain nombre élevé, comme

clip: rect (0px, 1000px, 1000px, -10px);/* Découpez le haut de l'ombre de la boîte * /

#box{
    box-shadow:             0px 0px 10px rgba(0, 0, 0, 0.7);
    -moz-box-shadow:     0px 0px 10px rgba(0, 0, 0, 0.7);
    -webkit-box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.7);
    clip:rect(0px, 210px, 200px, -10px); /* Clip the top and bottom of the box-shadow off */
    width:200px;
    height: 200px;
    position: absolute;
    top:50px;
    left:50px;
    background:#eee;
}
7
Alex

Oui, mais c'est assez fragile.

En utilisant le xhtml suivant:

<div id="wrap">

 <div id="content">

   <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. In sodales justo nec mauris aliquam vitae feugiat magna congue. Morbi dignissim volutpat dui id porttitor. Donec auctor feugiat dolor, at varius magna rhoncus sed. Vivamus a odio urna, iaculis dignissim lectus. Integer aliquam felis eu sapien vestibulum ornare. Vivamus nec euismod sapien. Mauris quis eros ligula, sed pulvinar sem. Aenean sodales tempor malesuada. Aliquam erat volutpat. Aenean vel eros velit, et porttitor elit. Phasellus volutpat blandit quam eu fringilla. Integer ornare convallis tincidunt. Suspendisse commodo iaculis est vulputate volutpat. Donec at massa arcu. Sed sit amet commodo mauris. Aliquam erat volutpat. Integer eu augue vel erat euismod volutpat eu vel massa. Curabitur id erat vitae nisi imperdiet scelerisque id ut arcu. Quisque commodo dolor vitae erat imperdiet consectetur.</p>

   <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. In sodales justo nec mauris aliquam vitae feugiat magna congue. Morbi dignissim volutpat dui id porttitor. Donec auctor feugiat dolor, at varius magna rhoncus sed. Vivamus a odio urna, iaculis dignissim lectus. Integer aliquam felis eu sapien vestibulum ornare. Vivamus nec euismod sapien. Mauris quis eros ligula, sed pulvinar sem. Aenean sodales tempor malesuada. Aliquam erat volutpat. Aenean vel eros velit, et porttitor elit. Phasellus volutpat blandit quam eu fringilla. Integer ornare convallis tincidunt. Suspendisse commodo iaculis est vulputate volutpat. Donec at massa arcu. Sed sit amet commodo mauris. Aliquam erat volutpat. Integer eu augue vel erat euismod volutpat eu vel massa. Curabitur id erat vitae nisi imperdiet scelerisque id ut arcu. Quisque commodo dolor vitae erat imperdiet consectetur.</p>

 </div>

</div>

Et le CSS suivant:

#wrap {width: 70%;
 margin: 1em auto;
 overflow: hidden;
 overflow-x: visible;
 }

#content
 {width: 90%;
 margin: 0 auto;
 -moz-box-shadow: 0 0 1em #ccc;
 -webkit-box-shadow: 0 0 1em #ccc;
 }

#content p
 {overflow-y: hidden;
 padding: 0.5em 0;
 }

(Démo en direct située ici: http://davidrhysthomas.co.uk/so/shadows.html .)

La fragilité se glisse si vous ajoutez des marges aux éléments contenus (en particulier le <p> elements, c'est pourquoi j'ai utilisé padding à la place). Mais, à peu près, appliquez le -moz-box-shadow (et/ou -webkit-box-shadow) à la #content div, et utilisez le #wrap div pour couper l'ombre, à l'aide de overflow-y: hidden; cela, bien sûr, le rend encore plus fragile en raison du nombre de navigateurs qui respectent overflow-y.

En revanche, les navigateurs qui interprètent le box-shadow traiter plus ou moins certainement de manière appropriée overflow-y.

La façon de le faire est de mettre la boîte avec l'ombre sous un div dont le débordement est réglé sur "caché". Par exemple, pour créer une ombre autour d'une boîte qui n'apparaît que sur les côtés gauche, supérieur et droit:

CSS:

#container {
    height: 101px;
    overflow: hidden;
    padding: 5px 5px 0;
    width: 105px;
}
#shadow-box {
   border:1px solid #aaa;
   width:100px;
   height:100px;
   box-shadow:0 0 4px 1px #666;
}

HTML:

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

Afficher:

enter image description here

Vous pouvez ajuster le rembourrage et la taille #container au clip approprié à vos besoins. Dans cet exemple, je coupe la bordure inférieure de la # shadow-box.

4
Redtopia

J'ai 2 solutions possibles qui produisent exactement l'effet désiré: une ombre de boîte "normale" sur certains bords et rien sur d'autres bords. De nombreuses solutions répertoriées dans ce document et dans d'autres S.O. les questions se traduisent par des ombres qui "se dissipent" lorsqu'elles se rapprochent de l'Edge qui ne doit pas avoir d'ombre, alors qu'en réalité je pense que la plupart des gens veulent une coupure nette.

Cependant, les deux solutions comportent des mises en garde.


Solution 1: clip-path (expérimental)

Si vous êtes disposé à utiliser une technologie expérimentale avec un support partiel, vous pouvez utiliser la propriété clip-path .

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

#container {
    box-shadow: 0 0 5px rgba(0,0,0,0.8);
    clip-path: inset(0px -5px 0px -5px);
}

Cela coupera le div en question à:

  • 0 pixels du haut
  • 5 pixels à l'extérieur du bord droit (pour inclure l'ombre)
  • 0 pixels à partir du bas
  • 5 pixels à l'extérieur du bord gauche (pour inclure l'ombre)

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

Un positionnement absolu n'est pas requis et la taille du div peut être flexible.


Solution 2: clip (obsolète)

Si:

  1. vous vouliez mettre position: absolute sur le div en question
  2. ET vous connaissez les dimensions de la div
  3. OU vous ne connaissez pas les dimensions du div mais vous êtes prêt à supprimer uniquement les ombres du haut et/ou de gauche

... vous pouvez utiliser la propriété déconseillée propriété clip .

Vous devez utiliser clip: rect(px, px, px, px); où les valeurs des pixels sont calculées en haut à gauche. Je l'ai utilisé comme suit pour couper l'ombre du cadre supérieur mais garder le bas et les côtés:

#container {
    position: absolute;
    box-shadow: 0 0 5px rgba(0,0,0,0.8);
    width: 100px;
    height: 100px;
    clip: rect(0px, 105px, 100px, -5px);
}

Ce qui précède coupera les ombres de boîte supérieures et inférieures tout en laissant les ombres de boîte gauche et droite de 5 pixels. Notez que la taille du div doit être connue.

Si la taille du div n'est pas connue, cette méthode ne fonctionnera que pour couper les ombres supérieure et gauche en utilisant quelque chose comme clip: rect(0, 3000px, 3000px, 0); ( notez la valeur massive des valeurs droite et inférieure pour permettre à la div d'être de n'importe quelle taille).

4
Luke

Je pense qu'il y aura toujours un peu de saignement sur les côtés adjacents qui deviendront plus évidents avec des valeurs de flou plus élevées. Vous pouvez compenser le fond perdu perçu en utilisant un flou faible et un décalage plus élevé sur les côtés sur lesquels vous souhaitez que l'ombre apparaisse. Par exemple, cela créerait une ombre visible sur les côtés et une ombre presque invisible en haut et en bas:

box-shadow: #888 3px 0px 2px, #888 -3px 0px 2px;
0
Jimmy Cuadra