Membuat bayangan kotak CSS3 di semua sisi kecuali satu

115

Saya memiliki bilah navigasi tab di mana saya ingin tab yang terbuka memiliki bayangan untuk membedakannya dari tab lain. Saya juga ingin seluruh bagian tab memiliki satu bayangan (lihat garis horizontal bawah) naik, menaungi bagian bawah semua tab kecuali yang terbuka.

Saya akan menggunakan box-shadowproperti CSS3 untuk melakukannya, tetapi saya tidak dapat menemukan cara untuk membuat bayangan hanya pada bagian yang saya inginkan.

Biasanya saya akan menutupi bayangan bawah tab yang terbuka dengan area konten (lebih tinggi z-index), tetapi dalam kasus ini area konten itu sendiri memiliki bayangan sehingga hanya menutupi tab.

Tata letak tab

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

Garis bayangan.

Bayangan akan naik dari garis horizontal, dan keluar dari garis vertikal.

                _______
               | |
_______________ | | _________________

Berikut adalah contoh langsungnya:

Ada bantuan di luar sana, jenius?

bloudermilk
sumber
23
@ the_drow Re: CSS3, saya ingin mempertimbangkan fitur desain seperti bayangan, sudut membulat, dll. sebagai hadiah bagi pengguna yang menggunakan browser modern.
bloudermilk
3
WOW ini persis apa yang saya butuhkan, senang pertanyaan sudah ada. Saya juga ingin menerapkan ini ke tab persis seperti yang Anda tunjukkan, wow wow wow: D
Jorge Israel Peña
Satu lagi cara hebat untuk menyelesaikan masalah ini adalah menggunakan elemen semu, lihat jawaban saya untuk lebih jelasnya.
Silver Ringvee
Lihat detail untuk solusi elemen semu di sini: stackoverflow.com/a/38372215/4769218
Silver Ringvee
Saya tahu ini adalah pertanyaan lama, tetapi apakah ukuran tabnya diketahui? Atau apakah mereka fleksibel? Saya bisa membayangkan tingginya mungkin diatur, tapi tidak lebarnya?
Luke

Jawaban:

72

Dalam contoh Anda, buat div di dalam #content dengan gaya ini

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

dan ubah gaya #content (hapus paddings) dan tambahkan bayangan

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

tambahkan bayangan ke tab:

#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
sumber
Ada sesuatu yang hilang dari solusi ini. Mengedit kodenya dan menerapkan gaya yang direkomendasikan, Anda masih berakhir dengan bayangan di atas tab 'dipilih'. Sepertinya ada luapan: tersembunyi yang hilang?
Bob Spryn
1
Ya. Anda akan membutuhkan overflow: hidden pada nav untuk membuatnya bekerja.
Bob Spryn
1
'Garis bayangan' yang ditampilkan dalam #content_over_shadowseharusnya benar-benar #contentbergaya.
AppleGrew
Nah solusi ini mabe benar pada tahun 2009, tetapi sekarang tidak. Jawaban yang benar adalah stackoverflow.com/a/9800481/835753
Guilherme Ferreira
Solusi dengan elemen pseudo: stackoverflow.com/a/38372215/4769218
Silver Ringvee
25

Potong dengan luapan.

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
sumber
3
Berikut juga contoh dengan memotongnya dengan overflow starikovs.com/2011/11/09/css3-one-side-shadow .
starikovs
Metode ini hanya akan bekerja jika Anda tidak menginginkan bayangan pada
sisi bawahnya
Bekerja dengan baik! Div induk dapat ditempatkan di kananz-index
Rvanlaak
Saat ini saya menggunakan solusi ini, saya mendapatkan beberapa masalah dengan elemen anak yang perlu meluap (seperti tombol suka facebook).
Loenix
1
Tidak terlalu berguna untuk desain yang paling responsif karena Anda harus mengatur ketinggian elemen
Jonathan Tonge
13

Anda dapat menggunakan beberapa bayangan CSS tanpa div lain untuk mendapatkan efek yang diinginkan, dengan peringatan tidak ada bayangan di sekitar sudut.

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>

Secara keseluruhan meskipun sangat tidak mengganggu.

Danny C
sumber
1
Ini akan menjadi solusi yang bagus, tetapi seperti yang Anda katakan, sudutnya miring. jsfiddle.net/mahemoff/ZStTr
mahemoff
1
Bekerja seperti pesona untuk kebutuhan bayangan inset saya dengan sudut membulat. Terima kasih!
Bruno Ely
9

Satu lagi, cara yang agak kreatif, untuk memecahkan masalah ini adalah menambahkan: setelah atau: sebelum elemen semu ke salah satu elemen. Dalam kasus saya, tampilannya seperti ini:

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

Lihat tangkapan layar, buat elemen semu menjadi merah agar lebih terlihat.

Lihat tangkapan layar, buat elemen semu menjadi merah agar lebih terlihat.

Silver Ringvee
sumber
7

Secara pribadi saya paling suka solusi yang ditemukan di sini: http://css3pie.com/demos/tabs/

Ini memungkinkan Anda memiliki status nol atau status hover dengan warna latar belakang yang masih memiliki bayangan dari konten di bawah yang melapisinya. Tidak yakin itu mungkin dengan metode di atas:

tab berbayang dengan status hover

MEMPERBARUI:

Sebenarnya saya salah. Anda dapat membuat solusi yang diterima mendukung status hover yang ditunjukkan di atas. Melakukan hal ini:

Alih-alih memiliki relatif positif di a, letakkan di kelas a.active dengan indeks-z yang lebih tinggi dari div #content Anda di bawah (yang memiliki bayangan di atasnya) tetapi lebih rendah dari indeks-z di content_wrapper.

Sebagai contoh:

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

lalu dengan css Anda:

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

Memperbarui:

clip-path sekarang didukung di semua browser utama.


Jawaban Asli:

Jika Anda ingin menggunakan teknologi eksperimental dengan dukungan parsial , Anda dapat menggunakan clip-pathproperti .

Ini akan menghasilkan efek yang diinginkan: bayangan kotak di sisi atas, kiri dan kanan dengan potongan bersih di tepi bawah.

Dalam kasus Anda, Anda akan menggunakan clip-path: inset (px px px px); di mana nilai piksel dihitung dari tepi yang dimaksud (lihat di bawah).

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

Ini akan memotong div yang dimaksud di:

  • 8 piksel di atas bagian atas (untuk menyertakan bayangan)
  • 8 piksel di luar tepi kanan (untuk menyertakan bayangan)
  • 0 piksel dari bawah (untuk menyembunyikan bayangan)
  • 8 piksel di luar tepi kiri (untuk menyertakan bayangan)

Perhatikan bahwa tidak ada koma yang diperlukan di antara nilai piksel.

Ukuran div bisa fleksibel.

Luke
sumber
Sayangnya ada celah di mana kedua bayangan tersebut saling tumpang tindih.
sbaechler
@sbaechler dapatkah Anda menjelaskan? Di mana bayangan tumpang tindih?
Luke
4

Anda juga dapat menutupi bayangan menggunakan beberapa bayangan kotak.

box-shadow: 0 10px 0 #fff, 0 0 10px #ccc;

pengguna2090657
sumber
1

Jika Anda menambahkan dua bentang untuk dihubungkan maka Anda bisa menggunakan dua, seperti:

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

pada satu rentang dan

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

yang lain. Mungkin berhasil!

Jika bayangan tumpang tindih, Anda bahkan bisa menggunakan 3 bayangan - satu 1px ke kiri, satu 1px ke kanan dan satu 1px ke atas, atau seberapa tebal Anda menginginkannya.

Bradshaw kaya
sumber
0

Saya melakukan semacam peretasan, tidak sempurna, tetapi kelihatannya oke:

<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);
}
pengguna2162298
sumber