Criação de uma sombra de caixa CSS3 em todos os lados, exceto um

115

Eu tenho uma barra de navegação com guias onde gostaria que a guia aberta tivesse uma sombra para diferenciá-la das outras guias. Também gostaria que toda a seção da guia tivesse uma única sombra (ver linha horizontal inferior) subindo, sombreando a parte inferior de todas as guias, exceto a aberta.

Vou usar a box-shadowpropriedade CSS3 para fazer isso, mas não consigo descobrir uma maneira de sombrear apenas as partes que desejo.

Normalmente, eu cobriria a sombra inferior da guia aberta com a área de conteúdo (mais alta z-index), mas, neste caso, a própria área de conteúdo tem uma sombra que acabaria cobrindo a guia.

Layout de guia

     _______ _______ _______
    | | | | | |
____ | _______ | __ | | __ | _______ | ______

Linha de sombra.

A sombra subiria a partir das linhas horizontais e para fora das linhas verticais.

                _______
               | |
_______________ | | _________________

Aqui está um exemplo ao vivo:

Alguma ajuda aí, gênios?

bloudermilk
fonte
23
@the_drow Re: CSS3, gosto de considerar recursos de design, como sombras projetadas, cantos arredondados, etc., uma recompensa para os usuários que usam navegadores modernos.
bloudermilk
3
WOW, isso é exatamente o que eu precisava, que bom que já existe uma pergunta. Eu também quero aplicar isso a uma guia exatamente como você mostrou, uau uau uau: D
Jorge Israel Peña
Outra ótima maneira de resolver esse problema é usar pseudoelementos, veja minha resposta para mais detalhes.
Silver Ringvee
Veja os detalhes da solução de pseudo-elemento aqui: stackoverflow.com/a/38372215/4769218
Silver Ringvee
Eu sei que essa é uma pergunta antiga, mas o tamanho das guias é conhecido? Ou eles são flexíveis? Posso imaginar que a altura pode ser definida, mas não a largura?
Lucas

Respostas:

72

Em sua amostra, crie um div dentro de #content com este estilo

#content_over_shadow {
    padding: 1em;
    position: relative; /* look at this */
    background:#fff;    /* a solid background (non transparent) */
}

e alterar o estilo do #content (remover preenchimentos) e adicionar sombra

#content {
    font-size: 1.8em;
    box-shadow: 0 0 8px 2px #888; /* line shadow */
}

adicionar sombras às guias:

#nav li a {
    margin-left: 20px;
    padding: .7em .5em .5em .5em;
    font-size: 1.3em;
    color: #FFF;
    display: inline-block;
    text-transform: uppercase;
    position: relative;
    box-shadow: 0 0 8px 2px #888; /* the shadow */
}
Peter
fonte
Há algo faltando nessa solução. Editando seu código e aplicando os estilos recomendados, você ainda acaba ficando com uma sombra sobre a aba 'selecionada'. Parece que há um estouro: falta oculta?
Bob Spryn,
1
Sim. Você precisaria de um overflow: hidden no nav para fazê-lo funcionar.
Bob Spryn,
1
A 'linha de sombra' mostrada em #content_over_shadowdeve realmente estar no #contentestilo de.
AppleGrew
Bem, esta solução talvez estivesse correta em 2009, mas agora não é. A resposta correta é stackoverflow.com/a/9800481/835753
Guilherme Ferreira
Uma solução com pseudoelemento: stackoverflow.com/a/38372215/4769218
Silver Ringvee
25

Corte-o com estouro.

div div {box-shadow:0 0 5px #000; height:20px}
div {overflow:hidden;height:25px; padding:5px 5px 0 5px}
<div><div>tab</div></div>

Kornel
fonte
3
Aqui está também um exemplo com o corte com overflow starikovs.com/2011/11/09/css3-one-side-shadow .
starikovs
Este método só funcionará quando for o lado inferior em que você não quer a sombra
andrhamm
Funciona bem! O div pai pode ser colocado no z-index
endereço
No momento, estou usando esta solução e estou tendo alguns problemas com o elemento filho que precisa transbordar (como o botão de curtir do Facebook).
Loenix
1
Não é muito útil para a maioria dos designs responsivos, pois você precisa definir a altura dos elementos
Jonathan Tonge
13

Você pode usar várias sombras CSS sem quaisquer outros divs para obter o efeito desejado, com a ressalva de que não há sombras nos cantos.

div.shadow {
    -webkit-box-shadow: 0 -3px 3px -3px black, 3px 0px 3px -3px black, -3px 0px 3px -3px black;
    -moz-box-shadow:    0 -3px 3px -3px black, 3px 0px 3px -3px black, -3px 0px 3px -3px black;
    box-shadow:         0 -3px 3px -3px black, 3px 0px 3px -3px black, -3px 0px 3px -3px black;
    height: 25px
}
 <div style="height: 25px"><div class="shadow">tab</div></div>

Globalmente, porém, é muito pouco intrusivo.

Danny C
fonte
1
Esta seria uma ótima solução, mas como você disse, os cantos são tortos. jsfiddle.net/mahemoff/ZStTr
mahemoff
1
Funcionou como um encanto para minhas necessidades de sombra inserida com cantos arredondados. Obrigado!
Bruno Ely
9

Outra forma bastante criativa de resolver este problema é adicionar: after ou: before pseudoelemento a um dos elementos. No meu caso, é assim:

#magik_megamenu>li:hover>a:after {
    height: 5px;
    width: 100%;
    background: white;
    content: '';
    position: absolute;
    bottom: -3px;
    left: 0;
}

Veja a imagem, fez o pseudo elemento vermelho para torná-lo mais visível.

Veja a imagem, fez o pseudo elemento vermelho para torná-lo mais visível.

Silver Ringvee
fonte
7

Pessoalmente, gosto mais da solução encontrada aqui: http://css3pie.com/demos/tabs/

Ele permite que você tenha um estado zero ou um estado de foco com uma cor de fundo que ainda tem a sombra do conteúdo abaixo sobreposta. Não tenho certeza se isso é possível com o método acima:

guia sombreada com estado flutuante

ATUALIZAR:

Na verdade, eu estava errado. Você pode fazer com que a solução aceita suporte o estado de foco mostrado acima. Faça isso:

Em vez de ter o relativo positivo em a, coloque-o na classe a.active com um índice z que é maior do que seu div #content abaixo (que tem a sombra), mas é menor que o índice z em seu content_wrapper.

Por exemplo:

<nav class="ppMod_Header clearfix">
    <h1 class="ppMod_PrimaryNavigation-Logo"><a class="ppStyle_Image_Logo" href="/">My company name</a></h1>
    <ul class="ppList_PrimaryNavigation ppStyle_NoListStyle clearfix">
        <li><a href="/benefits">Benefits</a></li>
        <li><a class="ppStyle_Active" href="/features">Features</a></li>
        <li><a href="/contact">Contact</a></li>
        <li><a href="/company">Company</a></li>
    </ul>
</nav>
<div id="ppPage-Body">
    <div id="ppPage-BodyWrap">
        content goes here
    </div>
</div>

então com seu css:

#ppPage-Body
    box-shadow: 0 0 12px rgba(0,0,0,.75)
    position: relative /* IMPORTANT PART */

#ppPage-BodyWrap
    background: #F4F4F4
    position: relative /* IMPORTANT PART */
    z-index: 4 /* IMPORTANT PART */


.ppList_PrimaryNavigation li a:hover
    background: #656565
    -webkit-border-radius: 6px 6px 0 0
    -moz-border-radius: 6px 6px 0 0
    border-radius: 6px 6px 0 0

.ppList_PrimaryNavigation li a.ppStyle_Active
    background: #f4f4f4
    color: #222
    -webkit-border-radius: 6px 6px 0 0
    -moz-border-radius: 6px 6px 0 0
    border-radius: 6px 6px 0 0
    -webkit-box-shadow: 0 0 12px rgba(0,0,0,0.75)
    -moz-box-shadow: 0 0 12px rgba(0,0,0,0.75)
    box-shadow: 0 0 12px rgba(0,0,0,0.75)
    position: relative /* IMPORTANT PART */
    z-index: 3 /* IMPORTANT PART */
Bob Spryn
fonte
7

Atualizar:

clip-path agora é compatível com todos os principais navegadores.


Resposta Original:

Se você deseja usar tecnologia experimental apenas com suporte parcial , pode usar a clip-pathpropriedade .

Isso produzirá o efeito desejado: uma sombra de caixa nos lados superior, esquerdo e direito com um corte limpo na borda inferior.

No seu caso, você usaria o caminho de clipe: inset (px px px px); onde os valores de pixel são calculados a partir da aresta em questão (veja abaixo).

#container {
    box-shadow: 0 0 8px 2px #888;
    clip-path: inset(-8px -8px 0px -8px);
}

Isso cortará o div em questão em:

  • 8 pixels acima do topo (para incluir a sombra)
  • 8 pixels fora da borda direita (para incluir a sombra)
  • 0 pixels da parte inferior (para ocultar a sombra)
  • 8 pixels fora da borda esquerda (para incluir a sombra)

Observe que nenhuma vírgula é necessária entre os valores de pixel.

O tamanho do div pode ser flexível.

Lucas
fonte
Infelizmente, há uma lacuna onde as duas sombras se sobrepõem.
sbaechler
@sbaechler você pode explicar? Onde as sombras se sobrepõem?
Lucas
4

você pode encobrir a sombra usando várias sombras de caixa também.

sombra da caixa: 0 10px 0 #fff, 0 0 10px #ccc;

user2090657
fonte
1

Se você adicionou dois vãos para se conectar, pode usar dois, algo como:

box-shadow: -1px -1px 1px #000;

em um período e

box-shadow: 1px -1px 1px #000;

em outro. Pode funcionar!

Se as sombras se sobrepõem, você pode até usar 3 sombras - uma 1px para a esquerda, uma 1px para a direita e uma 1px para cima, ou com a espessura que desejar.

Rich Bradshaw
fonte
0

Fiz uma espécie de hack, não perfeito, mas parece bom:

<ul class="tabs">
<li class="tab active"> Tab 1 </li>
<li class="tab"> Tab 2 </li>
<li class="tab"> Tab 3 </li>
</ul>

<div class="tab-content">Content of tab goes here</div>

SCSS

 .tabs { list-style-type: none; display:flex;align-items: flex-end;
  .tab {
    margin: 0;
    padding: 4px 12px;
    border: 1px solid $vivosBorderGrey2;
    background-color:$vivosBorderGrey2;
    color: $vivosWhite;
    border-top-right-radius: 8px;
    border-top-left-radius: 8px;
    border-bottom: 0;
    margin-right: 2px;
    font-size: 14px;
    outline: none;
    cursor: pointer;
    transition: 0.2s;
    &.active {
      padding-bottom: 10px;
      background-color: #ffffff;
      border-color: #eee;
      color: $vivosMedGrey;
      border-bottom-color: transparent;
      box-shadow: 0px -3px 8px -3px rgba(0, 0, 0, 0.1);
    }
    &:hover {padding-bottom: 10px;
    }
   } 

.tabContent {
  border: 1px solid #eee;
  padding:10px;
  margin-top: -1px;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
user2162298
fonte