Kształt ze skośną stroną (responsywny)

93

Próbuję utworzyć kształt jak na poniższym obrazku z ukośną krawędzią tylko z jednej strony (na przykład z dołu), podczas gdy pozostałe krawędzie pozostają proste.

CSS div z ukośną stroną

Próbowałem użyć metody granicznej (kod podano poniżej), ale wymiary mojego kształtu są dynamiczne i dlatego nie mogę użyć tej metody.

.shape {
    position: relative;
    height: 100px;
    width: 200px;
    background: tomato;
}
.shape:after {
    position: absolute;
    content: '';
    height: 0px;
    width: 0px;
    left: 0px;
    bottom: -100px;
    border-width: 50px 100px;
    border-style: solid;
    border-color: tomato tomato transparent transparent;
}
<div class="shape">
    Some content
</div>


Próbowałem również użyć gradientów jako tła (jak w poniższym kodzie), ale robi się pomieszane, gdy zmieniają się wymiary. Możesz zobaczyć, co mam na myśli, najeżdżając kursorem na kształt w poniższym fragmencie.

Jak mogę utworzyć ten kształt ze skośnym bokiem, a także być w stanie obsługiwać dynamiczne rozmiary ?

Złupić
źródło

Odpowiedzi:

128

Istnieje wiele sposobów tworzenia kształtu z ukośną krawędzią tylko z jednej strony.

Następujące metody nie obsługują rozmiarów dynamicznych, jak już wspomniano w pytaniu:

  • Metoda trójkąta granicznego z wartościami pikseli dla border-width.
  • Gradienty liniowe ze składnią kątową (np. 45 stopni, 30 stopni itp.).

Metody, które mogą obsługiwać rozmiary dynamiczne, opisano poniżej.


Metoda 1 - SVG

( Zgodność z przeglądarkami )

SVG może służyć do tworzenia kształtu za pomocą polygons lub paths. Poniższy fragment korzysta z polygon. Na górze kształtu można umieścić dowolną wymaganą treść tekstową.

Plusy

  • SVG jest przeznaczony do tworzenia skalowalnej grafiki i może dobrze działać przy wszystkich zmianach wymiarów.
  • Obramowanie i efekt najechania kursorem można osiągnąć przy minimalnym narzucie kodowania.
  • Do kształtu można również dodać obraz lub tło gradientowe.

Cons

  • Obsługa przeglądarki jest prawdopodobnie jedyną wadą, ponieważ IE8- nie obsługuje SVG, ale można to złagodzić za pomocą bibliotek takich jak Raphael, a także VML. Co więcej, obsługa przeglądarki nie jest gorsza niż inne opcje.

Metoda 2 - Gradientowe tło

( Zgodność z przeglądarkami )

Gradienty liniowe mogą być nadal używane do tworzenia kształtu, ale nie z kątami, jak wspomniano w pytaniu. Musimy użyć to [side] [side]składni (dzięki vals ) zamiast określać kąty. Po określeniu boków kąty gradientu są automatycznie dostosowywane na podstawie wymiarów kontenera.

Plusy

  • Kształt można uzyskać i zachować, nawet jeśli wymiary pojemnika są dynamiczne.
  • Efekt najechania można dodać, zmieniając kolor gradientu.

Cons

  • Efekt najechania aktywuje się nawet wtedy, gdy kursor znajduje się poza kształtem, ale w kontenerze.
  • Dodanie granic wymagałoby skomplikowanej manipulacji gradientem.
  • Gradienty są znane z tworzenia postrzępionych narożników, gdy szerokość (lub wysokość) jest bardzo duża.
  • Tła obrazu nie można używać na kształcie.

Metoda 3 - Przekształcenia pochylone

( Zgodność z przeglądarkami )

W tej metodzie pseudoelement jest dodawany, pochylany i pozycjonowany w taki sposób, że wygląda na to, że jedna z krawędzi jest pochylona / pod kątem. Jeśli górna lub dolna krawędź jest pochylona, ​​to skos powinien przebiegać wzdłuż osi Y, w przeciwnym razie obrót powinien odbywać się wzdłuż osi X. transform-originPowinny mieć boczny naprzeciw pochyłej stronie.

Plusy

  • Kształt można uzyskać nawet z brzegami.
  • Efekt najechania będzie ograniczony do kształtu.

Cons

  • Wymiary muszą rosnąć proporcjonalnie, aby kształt został zachowany, ponieważ gdy element jest pochylony, jego przesunięcie na osi Y zwiększa się wraz ze widthwzrostem i odwrotnie (spróbuj zwiększyć widthdo 200pxwe fragmencie). Więcej informacji na ten temat znajdziesz tutaj .

Metoda 4 - Przekształcenia perspektywy

( Zgodność z przeglądarkami )

W tej metodzie główny pojemnik jest obracany wzdłuż osi X lub Y z odrobiną perspektywy. Ustawienie odpowiedniej wartości na transform-originspowoduje powstanie ukośnej krawędzi tylko z jednej strony.

Jeśli górna lub dolna strona jest pochylona, ​​obrót powinien odbywać się wzdłuż osi Y, w przeciwnym razie obrót powinien odbywać się wzdłuż osi X. transform-originPowinny mieć boczny naprzeciw pochyłej stronie.

Plusy

  • Kształt można uzyskać za pomocą granic.
  • Wymiary nie muszą zwiększać się proporcjonalnie, aby kształt został zachowany.

Cons

  • Treść również zostanie obrócona, dlatego należy ją obrócić w przeciwną stronę, aby wyglądała normalnie.
  • Pozycjonowanie tekstu będzie żmudne, jeśli wymiary nie są statyczne.

Metoda 5 - ścieżka klipu CSS

( Zgodność z przeglądarkami )

W tej metodzie główny pojemnik jest przycinany do wymaganego kształtu za pomocą wielokąta. Punkty wielokąta należy zmodyfikować w zależności od strony, po której wymagana jest skośna krawędź.

Plusy

  • Kształt można zachować nawet w przypadku dynamicznej zmiany rozmiaru kontenera.
  • Efekt zawisu będzie doskonale ograniczony w granicach kształtu.
  • Obraz może również służyć jako tło kształtu.

Cons

  • Obsługa przeglądarek jest obecnie bardzo słaba.
  • Obramowania można dodawać, umieszczając element pozycjonowany absolutnie na górze kształtu i nadając mu niezbędny klip, ale poza punktem nie pasuje on dobrze podczas dynamicznej zmiany rozmiaru.

Metoda 6 - Płótno

( Zgodność z przeglądarkami )

Kanwy można również używać do tworzenia kształtu poprzez rysowanie ścieżek. Poniższy fragment zawiera demo. Na górze kształtu można umieścić dowolną wymaganą treść tekstową.

Plusy

  • Kształt można uzyskać i zachować, nawet jeśli wymiary pojemnika są dynamiczne. Można również dodać obramowania.
  • Efekt najechania można ograniczyć do granic kształtu przy użyciu pointInpathmetody.
  • Do kształtu można również dodać obraz lub tło gradientowe.
  • Lepszy wybór, jeśli potrzebne są efekty animacji w czasie rzeczywistym, ponieważ nie wymaga to manipulacji DOM.

Cons

  • Płótno jest oparte na rastrze, dlatego krawędzie ustawione pod kątem zostaną podzielone na piksele lub rozmyte po przeskalowaniu poza punkt * .

* - Unikanie pikselizacji wymagałoby ponownego malowania kształtu przy każdej zmianie rozmiaru widocznego obszaru. Jest to przykład tego tutaj , ale to jest na górze.

Złupić
źródło
36

Próbowałem użyć metody granicznej, ale wymiary mojego kształtu są dynamiczne i dlatego nie mogę użyć tej metody.


Metoda 7 - Jednostki rzutni ( Redukcja obramowania )

( Zgodność z przeglądarkami )

Viewport Units to wielka innowacja w CSS3. Chociaż zwykle możesz użyć wartości procentowych do dynamizacji właściwości, nie możesz tego zrobić dla border-widths ( ani dla font-sizes ).

Zamiast tego za pomocą jednostek rzutni możesz dynamicznie ustawiać szerokość obramowania wraz z rozmiarami obiektów w porównaniu z wymiarem rzutni.

Uwaga: wartości procentowe odnoszą się do obiektu nadrzędnego, a nie do rzutni (widoczny obszar okna).

Aby przetestować metodę, uruchom poniższy fragment kodu Full Page i zmień jego rozmiar zarówno w poziomie, jak iw pionie.

.shape {
    position: relative;
    height: 20vh;
    width: 40vw;
    background: tomato;
}
.shape:after {
    position: absolute;
    content: '';
    left: 0px;
    right: 0px;
    top: 20vh;
    border-width: 10vh 20vw;
    border-style: solid;
    border-color: tomato tomato rgba(0,0,0,0) rgba(0,0,0,0);
}
<div class="shape">Some content</div>

Zalety - (1) wszystko jest dynamiczne, przeglądarka ma szeroki zasięg.

Wady - (1) Należy zwrócić uwagę na jaki system operacyjny obsługuje przewijania z overflow: auto;.

Andrea Ligios
źródło
3
Wygląda na postrzępiony w najnowszej wersji Chrome.
Mr_Green
Prawdziwe! Wydaje mi się, że silniki przeglądarek nadal potrzebują trochę czasu, aby sprawnie to wyrenderować. Firefox ma również ten problem, gdy używa tej techniki z pikselami zamiast jednostek widoku, ale można go naprawić za pomocą rgba (,,, 0) zamiast przezroczystości. Na szczęście mamy teraz inne opcje;)
Andrea Ligios
1

Moje rozwiązanie jest inspirowane metodą o nazwie Method 7 - Viewport Units autorstwa Andrei Ligios, powyżej na tej stronie.

Użyłem także jednostki „poziomej” dla wysokości ( height:10vw), aby zachować podane proporcje w trapezie podczas zmiany szerokości okna nawigacji. Moglibyśmy nazwać tę metodę 7b - szerokość rzutni .

Ponadto, moim zdaniem , użycie dwóch zagnieżdżonych divs zamiast jednego i :afterselektora pozwala na lepsze dostrojenie stylów treści tekstu (np. text-alignItp.).

.dtrapz {
  position: relative;
  margin: 10px 40vw;
  width: 0;
  height: 10vw;
  border: none;
  border-right: 20vw solid #f22;
  border-bottom: 5vw solid transparent;
}

.dtcont {
  position: absolute;
  width: 20vw;
  height: 10vw;
  text-align: center;
  color: #fff;/* just aesthetic */
}
<div class="dtrapz">
  <div class="dtcont">Some content</div>
</div>

MattAllegro
źródło
@ Downvoter Cześć! Daj mi znać, co jest nie tak z moją odpowiedzią, abym mógł ją edytować lub usunąć, jeśli ma to sens! Nie jestem specjalistą, ale wydaje mi się, że można to zastosować na wielu stronach, pracować z dłuższą zawartością tekstu, tylko w zależności od szerokości :)
MattAllegro