Tworzenie cienia pól CSS3 ze wszystkich stron oprócz jednej

115

Mam pasek nawigacji z zakładkami, w którym chciałbym, aby otwarta karta miała cień, aby odróżnić ją od innych kart. Chciałbym również, aby cała sekcja kart miała pojedynczy cień (patrz dolna pozioma linia) przesuwający się w górę, zacieniający dół wszystkich kart z wyjątkiem otwartej.

Zamierzam użyć box-shadowwłaściwości CSS3, aby to zrobić, ale nie mogę znaleźć sposobu na cieniowanie tylko tych części, które chcę.

Zwykle zakrywałbym dolny cień otwartej karty obszarem zawartości (wyższym z-index), ale w tym przypadku sam obszar zawartości ma cień, więc po prostu zakryłby kartę.

Układ kart

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

Linia cienia.

Cień wychodził z poziomych linii i na zewnątrz pionowych linii.

                _______
               | |
_______________ | | _________________

Oto przykład na żywo:

Jakaś pomoc, geniusze?

bloudermilk
źródło
23
@the_drow Re: CSS3, lubię rozważać funkcje projektowe, takie jak cienie, zaokrąglone rogi itp., jako nagrodę dla tych użytkowników, którzy używają nowoczesnych przeglądarek.
bloudermilk
3
WOW, to jest dokładnie to, czego potrzebowałem, cieszę się, że pytanie już istnieje. Ja też chcę zastosować to do karty dokładnie takiej, jaką pokazałeś, wow wow wow: D
Jorge Israel Peña
Jeszcze jednym świetnym sposobem rozwiązania tego problemu jest użycie pseudoelementów, zobacz moją odpowiedź po więcej szczegółów.
Silver Ringvee,
Zobacz szczegóły rozwiązania pseudo-elementowego tutaj: stackoverflow.com/a/38372215/4769218
Silver Ringvee
Wiem, że to stare pytanie, ale czy znany jest rozmiar zakładek? A może są elastyczne? Mogę sobie wyobrazić, że można ustawić wysokość, ale nie szerokość?
Łukasz

Odpowiedzi:

72

W swoim przykładzie utwórz element div wewnątrz #content z tym stylem

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

i zmień styl #content (usuń dopełnienia) i dodaj cień

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

dodaj cienie do zakładek:

#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 */
}
Piotr
źródło
W tym rozwiązaniu czegoś brakuje. Edycja jego kodu i zastosowanie zalecanych stylów powoduje, że nadal pozostajesz cieniem nad zakładką „wybrane”. Wydaje się, że jest przepełnienie: ukryty brak?
Bob Spryn,
1
Tak. Potrzebowałbyś przepełnienia: ukrytego w nawigacji, aby działał.
Bob Spryn,
1
„Cień linii” pokazany w #content_over_shadowpowinien faktycznie być w #contentstylu.
AppleGrew
Cóż, to rozwiązanie mabe było poprawne w 2009 roku, ale teraz tak nie jest. Prawidłowa odpowiedź to stackoverflow.com/a/9800481/835753
Guilherme Ferreira
Rozwiązanie z pseudoelementem: stackoverflow.com/a/38372215/4769218
Silver Ringvee
25

Odetnij go przelewem.

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
źródło
3
Oto również przykład z odcięciem go za pomocą przepełnienia starikovs.com/2011/11/09/css3-one-side-shadow .
starikovs
Ta metoda będzie działać tylko wtedy, gdy jest to dolna strona, na której nie chcesz, aby cień był
andrhamm,
Działa świetnie! Nadrzędny div można umieścić na prawidłowymz-index
Rvanlaak
Obecnie używam tego rozwiązania i mam problemy z elementem podrzędnym, który musi się przepełnić (jak przycisk Facebooka).
Loenix
1
Niezbyt przydatne w przypadku większości responsywnych projektów, ponieważ musisz ustawić wysokość elementów
Jonathan Tonge
13

Możesz użyć wielu cieni CSS bez żadnych innych elementów div, aby uzyskać pożądany efekt, z zastrzeżeniem braku cieni w rogach.

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>

Ogólnie rzecz biorąc, jest bardzo dyskretny.

Danny C.
źródło
1
Byłoby to świetne rozwiązanie, ale jak powiedziałeś, rogi są nierówne. jsfiddle.net/mahemoff/ZStTr
mahemoff
1
Działał jak urok dla moich potrzeb w zakresie cienia z zaokrąglonymi rogami. Dzięki!
Bruno Ely
9

Innym, dość kreatywnym sposobem rozwiązania tego problemu jest dodanie pseudoelementu po lub: przed jednym z elementów. W moim przypadku wygląda to tak:

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

Spójrz na zrzut ekranu, uczyniłem pseudoelement czerwonym, aby był bardziej widoczny.

Spójrz na zrzut ekranu, uczyniłem pseudoelement czerwonym, aby był bardziej widoczny.

Silver Ringvee
źródło
7

Osobiście najbardziej podoba mi się znalezione tutaj rozwiązanie: http://css3pie.com/demos/tabs/

Pozwala na stan zerowy lub stan najechania z kolorem tła, na który nadal nakłada się cień z zawartości poniżej. Nie jestem pewien, czy jest to możliwe w przypadku powyższej metody:

zacieniona karta ze stanem najechania

AKTUALIZACJA:

Właściwie to się myliłem. Możesz sprawić, by zaakceptowane rozwiązanie obsługiwało stan najechania pokazany powyżej. Zrób to:

Zamiast mieć dodatni krewny na a, umieść go w klasie a.active z indeksem z wyższym niż twój #content div poniżej (który ma cień), ale jest niższy niż indeks z na twoim content_wrapper.

Na przykład:

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

następnie z twoim 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
źródło
7

Aktualizacja:

clip-path jest teraz obsługiwany we wszystkich głównych przeglądarkach.


Oryginalna odpowiedź:

Jeśli chcesz korzystać z technologii eksperymentalnej tylko częściowo , możesz skorzystać z tej clip-pathwłaściwości .

Daje to pożądany efekt: cień w kształcie pudełka na górze, po lewej i prawej stronie z czystym odcięciem na dolnej krawędzi.

W twoim przypadku użyłbyś clip-path: inset (px px px px); gdzie wartości pikseli są obliczane od danej krawędzi (patrz poniżej).

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

Spowoduje to obcięcie danego elementu DIV pod adresem:

  • 8 pikseli powyżej góry (aby uwzględnić cień)
  • 8 pikseli poza prawą krawędzią (aby uwzględnić cień)
  • 0 pikseli od dołu (aby ukryć cień)
  • 8 pikseli poza lewą krawędzią (aby uwzględnić cień)

Pamiętaj, że między wartościami pikseli nie są wymagane żadne przecinki.

Rozmiar elementu DIV może być elastyczny.

Łukasz
źródło
Niestety istnieje luka, w której dwa cienie nachodzą na siebie.
sbaechler
@sbaechler czy możesz to rozwinąć? Gdzie cienie się nakładają?
Łukasza
4

możesz również zakryć cień za pomocą wielu cieni pudełkowych.

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

user2090657
źródło
1

Jeśli dodałeś dwa przęsła do zaczepienia, możesz użyć dwóch, na przykład:

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

na jednym przęśle i

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

Na innej. Może działać!

Jeśli cienie nakładają się na siebie, możesz nawet użyć 3 cieni - jednego 1 piks. W lewo, jednego 1 piksela w prawo i jednego 1 piksela w górę, lub tak grubych, jak chcesz.

Rich Bradshaw
źródło
0

Zrobiłem coś w rodzaju włamania, nie idealnie, ale wygląda dobrze:

<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
źródło