Como criar uma sombra projetada apenas em um lado de um elemento?

230

Existe uma maneira de soltar a sombra apenas no fundo? Eu tenho um menu com 2 imagens ao lado do outro. Não quero uma sombra certa, porque ela se sobrepõe à imagem certa. Eu não gosto de usar imagens para isso, então existe uma maneira de soltá-lo apenas na parte inferior, como:

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

-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
fonte
8
Sua resposta aceita referencia box-shadow-bottomque não existe e não é suportada por ninguém. Consulte nicolasgallagher.com/css-drop-shadows-without-images/demo para obter técnicas legítimas de sombra de caixa.
Paul Irish
@ Paul ... Eu tive um erro de digitação, é fixo.
Hristo 29/03
1
Os comentários no seu exemplo de CSS são enganosos - filtertambém funcionarão no IE8 e IE9. Não há necessidade -ms-filterneste caso.
Mathias Bynens 29/03
Você pode adaptar este realista sombra inserção css: stackoverflow.com/a/20596554/1491212
Armel Larcier

Respostas:

234

ATUALIZAÇÃO 4

O mesmo que a atualização 3, mas com css moderno (= menos regras), para que nenhum posicionamento especial no pseudo elemento seja necessário.

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

ATUALIZAÇÃO 3

Todas as minhas respostas anteriores têm usado marcação extra para criar esse efeito, o que não é necessariamente necessário. Eu acho que essa é uma solução muito mais limpa ... o único truque é brincar com os valores para obter o posicionamento correto da sombra, bem como a força / opacidade correta da sombra. Aqui está um novo violino, usando pseudo-elementos :

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

ATUALIZAÇÃO 2

Aparentemente, você pode fazer isso com apenas um parâmetro extra para o CSS box-shadow, como todos os demais apontaram. Aqui está a demonstração:

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;

Essa seria uma solução melhor. O parâmetro extra adicionado é descrito como:

O quarto comprimento é uma distância de propagação. Valores positivos fazem com que a forma da sombra se expanda em todas as direções pelo raio especificado. Valores negativos fazem com que a forma da sombra se contraia.

ATUALIZAR

Confira a demonstração em jsFiddle: http://jsfiddle.net/K88H9/4/

O que eu fiz foi criar um "elemento de sombra" que se esconderia atrás do elemento real que você gostaria de ter uma sombra. Eu fiz a largura do "elemento de sombra" ser exatamente menos larga que o elemento real em 2 vezes a sombra que você especificar; então eu alinhei corretamente.

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

Resposta original

Sim, você pode fazer isso com a mesma sintaxe que você forneceu. O primeiro valor controla o posicionamento horizontal e o segundo valor controla o posicionamento vertical. Portanto, basta definir o primeiro valor como 0pxe o segundo como o deslocamento que você deseja da seguinte maneira:

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

Para mais informações sobre sombras de caixas, confira estas:

Eu espero que isso ajude.

Hristo
fonte
2
Você não precisa necessariamente adicionar uma div vazia para obter uma sombra borrada. Esse terceiro valor na declaração: box-shadow: 0 2px 4px #000000é um valor de desfoque. Veja aqui http://jsfiddle.net/K88H9/7/ . Mas você notará que há um pouco de desfoque à esquerda e à direita do elemento, onde na solução de Hristo não existe.
9
Não há propriedade box-shadow-bottom e esse efeito definitivamente não precisa de um elemento extra. Que nojo.
Lea Verou
7
box-shadow-bottom, embora criativo, não existe realmente.
miketaylr
3
caras frio ... foi um erro de digitação friggin'
Hristo
1
@gryzzly ... Eu editei minha resposta, não vi meu erro de digitação até que todos apontassem. Me desculpe por isso.
Hristo 29/03
71

Basta usar o parâmetro spread para diminuir a sombra:

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

Demonstração ao vivo: http://dabblet.com/gist/a8f8ba527f5cff607327

Para não ver nenhuma sombra nas laterais, o (valor absoluto do) raio de propagação (quarto parâmetro) precisa ser o mesmo que o raio de desfoque (terceiro parâmetro).

Lea Verou
fonte
1
isso realmente não funciona. À primeira vista, parece que a sombra está apenas no fundo, mas na verdade ainda se espalha pelos lados. Os exemplos de Everbody são com uma caixa azul escura ... deixe a caixa branca e você verá toda a sombra.
Chris L
@ Chris M: apenas incremente o parâmetro spread: tente 4 exemplos com box-shadow:0 8px 4px -6pxe você verá apenas a sombra inferior!
T30
1
mais uma vez, faça a caixa BRANCA como neste violino e você ainda verá sombras por todos os lados e agora ela não chega até o fundo. até onde você está disposto a ir no parâmetro spread para se livrar dos lados? Além disso, provavelmente é melhor para alguém com 151 representantes não editar a resposta de alguém com 7k representantes. deixe em um comentário.
Chris L
1
@ T30 É claro que você pode se livrar dos lados reduzindo ainda mais o parâmetro de propagação. Mas agora sua sombra não está nem perto da largura da sua caixa. Você tem uma caixa de 84 pixels com uma sombra de 72 pixels.
Chris L
1
Resposta atualizada. Mas, basicamente, além de reduzir o raio de propagação e ajustar o deslocamento em Y, não há muito o que se possa fazer. Talvez use um gradiente em vez de uma sombra? Além disso, não me importo com as pessoas editando minhas postagens, mas não aprecio as pessoas editando minhas postagens para adicionar frases escritas em algum idioma parecido com o inglês. Também não sou um falante nativo de inglês e compreendo os desafios, mas se estivesse editando a postagem de outra pessoa, sentiria responsabilidade suficiente para, pelo menos, verificar duas vezes se o que eu adicionei faz sentido e que a gramática não é embaraçosamente errado.
Lea Verou
30

Se você tiver uma cor fixa no plano de fundo, poderá ocultar o efeito de sombra lateral com duas sombras de máscara com a mesma cor de plano de fundo e desfoque = 0, por exemplo:

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

Observe que a sombra preta deve ser a última e tem uma margem negativa (-3px) para impedir que ela se estenda além dos cantos.

Aqui o violino (mude a cor das sombras mascaradas para ver como ele realmente funciona).

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

insira a descrição da imagem aqui

T30
fonte
1
Seria muito melhor usar a transparentcor para as sombras mascaradas, não?
Angel Joseph Piscola
@AngelJosephPiscola: dica inteligente .. Implementada na resposta, obrigado!
T30
@ T30 incrível, mas nota que, com uma máscara transparente você não deve precisar um fundo fixo de cor;)
Anjo Joseph piscola
Eu testei melhor e a sombra transparente não funciona , então revirei as últimas edições
T30
6

Eu acho que é isso que você está procurando?

.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
fonte
2
Adoro quando as pessoas simplesmente não entendem. Sim, ele está mexendo com a propagação da primeira sombra (branca) que cobrirá a margem da sombra real (preta). Esta é a única maneira sadia de obter uma sombra unidirecional perfeita. Especialmente útil quando você precisa ter a mesma sombra em 2 partes de um menu.
Zeno Popovici
5

É sempre melhor ler as especificações . Não há box-shadow-bottompropriedade e, como Lea aponta, você deve sempre colocar a propriedade não prefixada na parte inferior, após as prefixadas.

Então é:

.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
fonte
1
Não há sombra dos lados
Shinzou
2

Que tal usar apenas uma div contendo o estouro definido como oculto e algum preenchimento na parte inferior? Esta parece ser a solução mais simples.

Lamento dizer que não pensei nisso, mas vi em outro lugar .

Usando um elemento para quebrar o elemento, obtendo a sombra da caixa e um estouro: oculto no invólucro, você pode fazer a sombra da caixa extra desaparecer e ainda ter uma borda utilizável. Isso também corrige o problema em que o elemento é menor como parece, por causa da propagação.

Como isso:

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

O conteúdo entra aqui

Ainda é uma solução inteligente quando precisa ser feita em CSS puro!

Como dito por Jorgen Evens .

Ben
fonte
+1 para a solução. Além do padding-bottom(digamos 5px), você também pode definir um valor negativo margin-bottom(de -5px) para compensar o espaço adicionado.
Fabio.sang
2

Você também pode usar clip-pathpara recortar (ocultar) todas as arestas que estão transbordando, mas a que você deseja mostrar:

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

Consulte caminho do clipe (MDN) . Os argumentos para polygonsão o ponto superior esquerdo , o ponto superior direito , o ponto inferior direito e o ponto inferior esquerdo . Ao definir a borda inferior como 200%(ou qualquer número maior que 100%), você restringe seu estouro apenas à borda inferior.

theengineear
fonte
Então ... em termos básicos, o clip-path é o excesso: propriedade oculta nos esteróides. Isso está limpo. ;)
Craig
1

Eu também precisava de uma sombra, mas apenas sob uma imagem e coloquei um pouco à esquerda e à direita. Isso funcionou para mim:

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

O elemento ao qual é aplicado é uma imagem em toda a página (980px x 300px).

Se ajudar a mexer nas configurações, elas serão executadas da seguinte maneira:

sombra horizontal, sombra vertical, distância do borrão, propagação (tamanho da sombra) e cor.

Chris9
fonte
1

É melhor procurar sombra:

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

esse código está sendo usado atualmente na web stackoverflow.

Kamlesh
fonte
1

Esta caneta de código (não por mim) demonstra uma maneira super simples de fazer isso e os outros lados sozinhos:

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

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

David Daudelin
fonte
0

Se o seu plano de fundo for sólido (ou você pode reproduzi-lo usando CSS), use o gradiente linear dessa maneira:

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>

Isso gerará um gradiente de 5px na parte inferior do elemento, do preto com 30% de opacidade ao completamente transparente. O restante do elemento possui fundo branco. É claro que, alterando as duas últimas paradas de cores do gradiente linear, você pode tornar o fundo completamente transparente.

Tibo
fonte
0

Você também pode fazer um gradiente na parte inferior - isso foi útil para mim porque a sombra que eu queria estava em um elemento que já era semitransparente, para que eu não precisasse me preocupar com nenhum recorte:

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

Apenas faça com que as propriedades "bottom" e "height" correspondam e defina seus valores de rgba para o que você deseja que eles estejam na parte superior / inferior da sombra

mheavers
fonte
0

Você pode fazer isso assim:

Sintaxe geral:

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

Exemplo: queremos fazer apenas uma sombra da caixa inferior com a cor vermelha,

para fazer isso, precisamos definir todas as opções de lados, onde temos que definir as opções de sombra da caixa inferior e definir todas as outras como vazias da seguinte maneira:

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

atualize para outra pessoa sua resposta nos lados transparentes, em vez do branco, para que também funcione em outros fundos coloridos.

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

sombra interior

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