Come creare un'ombra discendente solo su un lato di un elemento?


230

C'è un modo per far cadere l'ombra solo sul fondo ?. Ho un menu con 2 immagini una accanto all'altra. Non voglio un'ombra giusta perché si sovrappone all'immagine giusta. Non mi piace usare le immagini per questo, quindi c'è un modo per lasciarlo solo sul fondo come:

box-shadow-bottom: 10px #FFF; o simili?

-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');

8
La tua risposta accettata fa riferimento a riferimenti box-shadow-bottominesistenti e non supportati da nessuno. Vedi nicolasgallagher.com/css-drop-shadows-without-images/demo per le tecniche di box-shadow legittime.
Paul Irish

@Paul ... ho avuto un refuso, è stato corretto.
Hristo,

1
I commenti nel tuo esempio CSS sono fuorvianti - filterfunzioneranno anche in IE8 e IE9. Non è necessario -ms-filterin questo caso.
Mathias Bynens,

Puoi adattare questa realistica css shadow: stackoverflow.com/a/20596554/1491212
Armel Larcier,

Risposte:


234

AGGIORNAMENTO 4

Come l'aggiornamento 3 ma con i moderni CSS (= meno regole) in modo che non sia richiesto alcun posizionamento speciale sullo pseudo elemento.

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

AGGIORNAMENTO 3

Tutte le mie precedenti risposte hanno utilizzato un markup aggiuntivo per creare questo effetto, che non è necessariamente necessario. Penso che questo a soluzione molto più pulita ... l'unico trucco è giocare con i valori per ottenere il giusto posizionamento dell'ombra e la giusta forza / opacità dell'ombra. Ecco un nuovo violino, usando pseudo-elementi :

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

AGGIORNAMENTO 2

Apparentemente, puoi farlo con solo un parametro aggiuntivo al CSS di box-shadow come tutti gli altri hanno appena sottolineato. Ecco la demo:

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;

Questa sarebbe una soluzione migliore. Il parametro aggiuntivo che viene aggiunto è descritto come:

La quarta lunghezza è una distanza estesa. I valori positivi fanno sì che la forma dell'ombra si espanda in tutte le direzioni entro il raggio specificato. I valori negativi causano la contrazione della forma dell'ombra.

AGGIORNARE

Guarda la demo su jsFiddle: http://jsfiddle.net/K88H9/4/

Quello che ho fatto è stato creare un "elemento ombra" che si nascondesse dietro l'elemento reale che si vorrebbe avere un'ombra. Ho reso la larghezza dell '"elemento ombra" per essere esattamente meno ampia dell'elemento reale di 2 volte l'ombra specificata; poi l'ho allineato correttamente.

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

Risposta originale

Sì, puoi farlo con la stessa sintassi che hai fornito. Il primo valore controlla il posizionamento orizzontale e il secondo valore controlla il posizionamento verticale. Quindi basta impostare il primo valore su 0pxe il secondo su qualunque offset si desideri come segue:

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

Per ulteriori informazioni sulle ombre delle scatole, dai un'occhiata a questi:

Spero che aiuti.


2
Non è necessario aggiungere necessariamente un div vuoto per ottenere un'ombra sfocata. Quel terzo valore nella dichiarazione: box-shadow: 0 2px 4px #000000è un valore di sfocatura. Vedi qui http://jsfiddle.net/K88H9/7/ . Ma noterai che c'è un po 'di sfocatura alla sinistra e alla destra dell'elemento, dove nella soluzione di Hristo non c'è.

9
Non esiste una proprietà box-shadow-bottom e questo effetto sicuramente non ha bisogno di un elemento aggiuntivo. Che schifo.
Lea Verou,

7
box-shadow-bottom, sebbene creativo, in realtà non esiste.
miketaylr,

3
ragazzi freddi ... è stato un errore di battitura
Hristo,

1
@gryzzly ... Ho modificato la mia risposta, non ho visto il mio errore di battitura fino a quando tutti non lo hanno sottolineato. Mi dispiace per quello.
Hristo,

71

Basta usare il parametro spread per ridurre l'ombra:

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

Demo live: http://dabblet.com/gist/a8f8ba527f5cff607327

Per non vedere alcuna ombra sui lati, il (valore assoluto del) raggio di diffusione (4 ° parametro) deve essere uguale al raggio di sfocatura (3o parametro).


1
questo in realtà non funziona. a prima vista sembra che l'ombra sia solo sul fondo ma in realtà si diffonde ancora oltre i lati. Gli esempi di Everbody sono con una scatola blu abbastanza scura ... rendi bianca la scatola e vedrai tutta l'ombra.
Chris L,

@Chris M: basta incrementare il parametro spread: prova 4 esempio con box-shadow:0 8px 4px -6pxe vedrai solo l'ombra in basso!
T30,

1
ancora una volta, rendi la scatola BIANCA come in questo violino e vedrai ancora l'ombra fino ai lati e anche ora non ce la fa fino in fondo. fino a che punto sei disposto ad andare sul parametro spread per sbarazzarti dei lati? Inoltre, probabilmente è meglio che qualcuno con 151 rappresentanti non modifichi la risposta di qualcuno con 7k rappresentanti. lascialo in un commento.
Chris L,

1
@ T30 Naturalmente puoi eventualmente eliminare i lati riducendo ulteriormente il parametro di diffusione. Ma ora la tua ombra non è vicino alla larghezza della tua scatola. Hai una scatola 84px con un'ombra 72px.
Chris L,

1
Risposta aggiornata. Ma fondamentalmente, a parte ridurre il raggio di diffusione e regolare l'offset Y, non c'è molto che si possa fare. Forse usi un gradiente anziché un'ombra? Inoltre, non mi dispiace che le persone modificino i miei post, ma non apprezzo le persone che modificano i miei post per aggiungere frasi scritte in un linguaggio simile a Engrish. Non sono neanche un madrelingua inglese e capisco le sfide, ma se stavo modificando il post di qualcun altro, mi sentirei abbastanza responsabile di almeno ricontrollare che ciò che ho aggiunto ha senso e la grammatica non lo è imbarazzantemente sbagliato.
Lea Verou,

30

Se hai un colore fisso sullo sfondo, puoi nascondere l'effetto dell'ombra laterale con due ombre di mascheramento aventi lo stesso colore dello sfondo e sfocatura = 0, esempio:

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

Nota che l'ombra nera deve essere l'ultima e ha una diffusione negativa (-3px) per evitare che si estenda oltre gli angoli.

Qui il violino (cambia il colore delle ombre di mascheratura per vedere come funziona davvero ).

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

inserisci qui la descrizione dell'immagine


1
Sarebbe molto meglio usare il transparentcolore per mascherare le ombre, no?
Angel Joseph Piscola,

@AngelJosephPiscola: suggerimento intelligente .. Implementato nella risposta, grazie!
T30,

@ T30 fantastico, ma nota che con una maschera trasparente non devi avere uno sfondo a colori fisso;)
Angel Joseph Piscola,

L'ho testato meglio e l'ombra trasparente non funziona , quindi ho eseguito il rollback delle ultime modifiche
T30

6

Penso che sia questo ciò che cerchi?

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


2
Lo adoro quando le persone semplicemente non capiscono. Sì, sta scherzando con la diffusione della prima ombra (bianca) che coprirà il margine della vera ombra (nero). Questo è l'unico modo sano per ottenere un'ombra unidirezionale perfetta. Utile specialmente quando devi avere la stessa ombra su 2 parti di un menu.
Zeno Popovici,

5

È sempre meglio leggere le specifiche . Non esiste alcuna box-shadow-bottomproprietà e, come sottolinea Lea, dovresti sempre posizionare la proprietà senza prefisso in fondo, dopo quelle con prefisso.

Così è:

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


1
C'è ombra dai lati
shinzou,

2

Che ne dite di usare solo un div contenente che ha overflow impostato su nascosto e un po 'di riempimento nella parte inferiore? Questa sembra la soluzione più semplice.

Mi dispiace dire che non ci ho pensato, ma l'ho visto altrove .

Usando un elemento per avvolgere l'elemento ottenendo l'ombra della scatola e uno straripamento: nascosto sull'involucro potresti far scomparire l'ombra della scatola aggiuntiva e avere ancora un bordo utilizzabile. Questo risolve anche il problema in cui l'elemento è più piccolo come sembra, a causa della diffusione.

Come questo:

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

Il contenuto va qui

Ancora una soluzione intelligente quando deve essere fatto in puro CSS!

Come detto da Jorgen Evens .


+1 per la soluzione. Oltre a padding-bottom(diciamo 5px), puoi anche impostare un negativo margin-bottom(di -5px) per compensare lo spazio aggiunto.
fabio.sang,

2

Puoi anche usare clip-pathper tagliare (nascondere) tutti i bordi traboccanti ma quello che vuoi mostrare:

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

Vedi clip-path (MDN) . Gli argomenti da utilizzare polygonsono il punto in alto a sinistra , il punto in alto a destra , il punto in basso a destra e il punto in basso a sinistra . Impostando il bordo inferiore su 200%(o qualsiasi numero maggiore di 100%) si limita il trabocco solo al bordo inferiore.


Quindi ... in termini di base, il percorso di clip è l'overflow: proprietà nascoste sugli steroidi. Questo è pulito ;)
Craig,

1

Avevo anche bisogno di un'ombra ma solo sotto un'immagine e impostato leggermente a sinistra e a destra. Questo ha funzionato per me:

.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'elemento a cui viene applicato è un'immagine a livello di pagina (980 px x 300 px).

Se aiuta a giocherellare con le impostazioni, funzionano come segue:

ombra orizzontale, ombra verticale, distanza di sfocatura, diffusione (ovvero dimensione dell'ombra) e colore.


1

È meglio cercare l'ombra:

.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);
}

questo codice è attualmente in uso sul web StackOverflow.



0

Se lo sfondo è solido (o è possibile riprodurlo tramite CSS), è possibile utilizzare il gradiente lineare in questo modo:

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>

Ciò genererà un gradiente di 5px nella parte inferiore dell'elemento, dal nero con un'opacità del 30% a completamente trasparente. Il resto dell'elemento ha uno sfondo bianco. Naturalmente, modificando le ultime 2 interruzioni di colore del gradiente lineare, è possibile rendere lo sfondo completamente trasparente.


0

Potresti anche fare solo una sfumatura sul fondo: questo mi è stato utile perché l'ombra che volevo era su un elemento che era già semi-trasparente, quindi non dovevo preoccuparmi di alcun ritaglio:

&: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%);
    }

Basta far corrispondere le proprietà "bottom" e "height" e impostare i valori di rgba su qualsiasi cosa tu voglia che siano nella parte superiore / inferiore dell'ombra


0

Puoi farlo in questo modo:

Sintassi generale:

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

Esempio: vogliamo creare solo un'ombra in basso con il colore rosso,

quindi per fare ciò dobbiamo impostare tutte le opzioni dei lati in cui dobbiamo impostare le opzioni di ombra nella casella in basso e impostare tutte le altre come vuote come segue:

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

-1

aggiorna su qualcun altro la sua risposta sui lati trasparenti anziché sul bianco in modo che funzioni anche su altri sfondi di colore.

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>


-3

Ombra interiore

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.