Alexey Shepelev
Alexey ShepelevSenior Ruby on Rails Developer @ Altoros

Poznaj 22 sztuczki i właściwości CSS

Odkryj mniej znane, ale przydatne właściwości CSS i twórz lepszy frontend.
2.09.202110 min
Poznaj 22 sztuczki i właściwości CSS

Dzisiaj opowiem o kilku właściwościach CSS, o których rzadko wspomina się w literaturze technicznej, a które moim zdaniem są przydatne. Szczególnie jeżeli zależy Ci na szybkim tworzeniu interfejsów webowych.

Wiele z omawianych właściwości ma charakter eksperymentalny. Większość z nich jest obsługiwana przez wszystkie nowoczesne przeglądarki. Jeśli jednak zdecydujesz się na użycie którejkolwiek z tych właściwości w produkcji, rozważ odwiedzenie strony Can I Use, aby upewnić się, że są one obsługiwane. Zaczynajmy!

grid + place-items


Technika ta pozwala na wyrównanie elementów w poziomie i w pionie za pomocą zaledwie dwóch linii kodu.

.parent {
  display: grid;
  place-items: center;
}


place-items jest skrótem dla justify-items i align-items.

Właściwość ta może być zastosowana do jednej lub kilku komórek (dzieci) jednocześnie.

flex + margin

Innym nowoczesnym sposobem na wyrównanie elementów w poziomie i w pionie jest użycie kombinacji display: flex i margin: auto.

.parent {
  display: flex;
}

.child {
  margin: auto;
}


Można powiedzieć, że to samo da się zrobić za pomocą poniższego:

.parent {
  display: flex;
  justify-content: center;
  align-items: center;
}

flex + gap

Skoro już mówimy o Flexbox, to warto wspomnieć, że w końcu mamy możliwość ustawiania odstępów pomiędzy elementami flexa za pomocą właściwości gap (co jest mega przydatne):

.parent {
  display: flex;
  flex-wrap: wrap;
  gap: 1em;
}

inline-flex

Ta właściwość pozwala na tworzenie elementów inline, które posiadają cechy Flexbox. Przykład wart jest wielu słów:

<span>?</span>
<span>?</span>
<span>?</span>
<span>?</span>
body {
  margin: 0;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 0.5em;
  background: #fbfbfb;
}
span {
  width: 2.5em;
  height: 2.5em;
  /* --- */
  display: inline-flex;
  justify-content: center;
  align-items: center;
  /* --- */
  background: #1266f1;
  border-radius: 30%;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
  font-size: 1.1rem;
}

columns

Technika ta pozwala na podział tekstu na kolumny. Właściwość column-count określa liczbę kolumn, column-gap określa wielkość odstępu między kolumnami, a column-rule określa styl pionowej linii między kolumnami.

columns jest skrótem dla column-count i column-width.

<p>
  Lorem ipsum dolor sit amet consectetur adipisicing elit. Quis reprehenderit inventore ad libero officia, necessitatibus laudantium corporis veniam quae, fugiat dolores quaerat corrupti tempore ipsa consequuntur similique explicabo ducimus commodi expedita. Dolore commodi nesciunt harum? Consequuntur, voluptatibus odio! Maiores non alias autem tempore corrupti, animi accusamus repudiandae nam. Autem at explicabo molestias dignissimos repellendus, magnam laudantium ea quisquam, quam, tenetur adipisci facere quas. Accusantium architecto iste eius tempore consequatur quidem officiis delectus eaque sequi rem! Nesciunt voluptatum tempora voluptatem a sit, minima excepturi quaerat quasi soluta aspernatur quia explicabo incidunt, fugiat animi. Dolor provident corporis magni voluptate vel non earum?
</p>
@import url("https://fonts.googleapis.com/css2?family=Montserrat&display=swap");
body {
  margin: 0;
  background: #262626;
  font-family: "Montserrat", sans-serif;
  color: #fbfbfb;
}
p {
  margin: 1em;
  /* --- */
  column-count: 3;
  column-gap: 2em;
  column-rule: 1px dotted;
  /* --- */
}

@media (max-width: 768px) {
  p {
    column-count: 2;
  }
}

@media (max-width: 512px) {
  p {
    column-count: 1;
  }
}

background-repeat

Właściwość background-repeat ustawia sposób wypełniania tła określonym obrazem. Wartość round równomiernie rozkłada obrazy na całej szerokości kontenera, podczas gdy wartość space dodaje niewielką przestrzeń pomiędzy obrazami:

<div class="repeat"></div>
<div class="round"></div>
<div class="space"></div>
body {
  margin: 0;
  height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: #fbfbfb;
}
div {
  width: 300px;
  height: 64px;
  background-image: url("https://pics.freeicons.io/uploads/icons/png/3733236321617275952-64.png");
}
.repeat {
  background-repeat: repeat;
}
.round {
  background-repeat: round;
}
.space {
  background-repeat: space;
}

background-blend-mode

Właściwość background-blend-mode określa sposób, w jaki obraz wyświetlany jako tło i kolor tła (lub wiele obrazków/kolorów tła) powinny się ze sobą mieszać.

Możliwe wartości:

  • color
  • color-burn
  • color-dodge
  • darken
  • difference
  • exclusion
  • hard-light
  • hue
  • lighten
  • luminosity
  • multiply
  • overlay
  • saturation
  • screen
  • soft-light


Czy kiedykolwiek pracowałeś z Photoshopem? Jeśli tak, to pewnie rozumiesz, o co tu chodzi.

Załóżmy, że mamy czarno-biały obraz, który chcemy użyć jako tło, ale jednocześnie chcemy, aby był kolorowy. Jak możemy to osiągnąć?

<h1>
  look at <br />
  the sky
</h1>
@import url("https://fonts.googleapis.com/css2?family=Audiowide&display=swap");
@keyframes show {
  from {
    opacity: 0;
    transform: scale(0) rotate(-180deg);
  }
  to {
    opacity: 1;
    transform: scale(1) rotate(0);
  }
}
body {
  margin: 0;
  height: 100vh;
  /* --- */
  background: url("https://images.pexels.com/photos/414659/pexels-photo-414659.jpeg?auto=compress&cs=tinysrgb&h=650&w=940"),
    linear-gradient(135deg, skyblue, steelblue 90%);
  background-blend-mode: overlay;
  /* --- */
  background-size: cover;
  display: grid;
  place-items: center;
}
h1 {
  font-family: "Audiowide", cursive;
  color: #00b74a;
  font-size: 4rem;
  text-transform: uppercase;
  text-align: center;
  text-shadow: 0 1px 2px #262626;
  animation: show 2s linear forwards;
}

background-clip

Właściwość background-clip określa, jak daleko kolor tła lub obraz tła powinien wykraczać poza obramowanie elementu. Moim zdaniem text jest najciekawszą wartością tej właściwości:

<p>nature</p>
@import url("https://fonts.googleapis.com/css2?family=Bungee&display=swap");
@keyframes pulse {
  from {
    transform: scale(1);
  }
  to {
    transform: scale(1.2);
  }
}
body {
  margin: 0;
  height: 100vh;
  display: grid;
  place-items: center;
  background-color: #fbfbfb;
  overflow: hidden;
}
p {
  font-family: "Bungee", cursive;
  font-size: 8rem;
  color: transparent;
  /* --- */
  background-image: url("https://images.pexels.com/photos/1179229/pexels-photo-1179229.jpeg?auto=compress&cs=tinysrgb&dpr=3&h=750&w=1260");
  -webkit-background-clip: text;
  background-clip: text;
  /* --- */
  background-size: cover;
  background-position: center;
  animation: pulse 2s linear infinite alternate;
}

filter

Właściwość filter pozwala na zastosowanie pewnych efektów wizualnych do elementów.

Możliwe wartości funkcji:

  • url()
  • blur()
  • brightness()
  • contrast()
  • drop-shadow()
  • grayscale()
  • hue-rotate()
  • invert()
  • opacity()
  • saturate()
  • sepia()


Zmiana motywów kolorystycznych strony (lub schematów) dla leniwych:

<input type="checkbox" class="theme" />
<p class="text">
  Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quam dolores quod debitis veritatis placeat nemo iste natus maxime. Adipisci quos quia veritatis nemo quaerat magnam dolorum tempora voluptatum deleniti consectetur enim ea facere nihil sed ut laborum hic, sapiente vel ratione harum, vero iusto laudantium. Porro accusantium a harum ipsam!
</p>
@import url("https://fonts.googleapis.com/css2?family=Montserrat&display=swap");
body {
  margin: 0;
  height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
.theme {
  cursor: pointer;
}
.theme:checked + .text {
  filter: invert();
}
.text {
  margin: 1em;
  padding: 1em;
  background: #262626;
  border-radius: 4px;
  font-family: "Montserrat", sans-serif;
  color: #fbfbfb;
  transition: 0.2s ease-in;
}


Na CSSgramie znajdziesz przykład użycia filter dla filtrów Instagrama.

drop-shadow

Właściwość filter ustawiona na drop-shadow(), w odróżnieniu od właściwości box-shadow, która jest podobna pod względem zastosowanego efektu, pozwala na dodanie cienia do samego obrazka (w formacie PNG), a nie do ramki, w której jest on umieszczony.

<input type="checkbox" class="theme" />
<p class="text">
  Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quam dolores quod debitis veritatis placeat nemo iste natus maxime. Adipisci quos quia veritatis nemo quaerat magnam dolorum tempora voluptatum deleniti consectetur enim ea facere nihil sed ut laborum hic, sapiente vel ratione harum, vero iusto laudantium. Porro accusantium a harum ipsam!
</p>
@import url("https://fonts.googleapis.com/css2?family=Montserrat&display=swap");
body {
  margin: 0;
  height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
.theme {
  cursor: pointer;
}
.theme:checked + .text {
  filter: invert();
}
.text {
  margin: 1em;
  padding: 1em;
  background: #262626;
  border-radius: 4px;
  font-family: "Montserrat", sans-serif;
  color: #fbfbfb;
  transition: 0.2s ease-in;
}

object-fit

Właściwość object-fit kontroluje proporcje zastąpionych elementów, takich jak img i video, jeśli mają one szerokość lub wysokość; a także ich skalowanie.

Wartość scale-down pozwala np. na zachowanie proporcji obrazu niezależnie od rozmiaru ramki:

<img src="https://pics.freeicons.io/uploads/icons/png/21088442871540553614-64.png" alt="js" />
<img src="https://pics.freeicons.io/uploads/icons/png/20167174151551942641-64.png" alt="react" />
<img src="https://pics.freeicons.io/uploads/icons/png/191213921552037062-64.png" alt="vue" />
body {
  margin: 0;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 1em;
  background-color: #fbfbfb;
}
img {
  width: 100px;
  height: 100px;
  /*  ---  */
  object-fit: scale-down;
  /*  ---  */
  border: 1px dashed #262626;
  border-radius: 4px;
}


Właściwość object-position jest używana do wyrównywania zawartości dowolnego wybranego zastępowanego elementu wewnątrz ramki.

cursor

Czy wiesz, że oprócz ikon kursora dostarczanych przez przeglądarkę (np. cursor: pointer), możemy również definiować własne obrazki i SVG?

<div class="image">image</div>
<div class="svg">svg</div>
body {
  margin: 0;
  height: 100vh;
  background-color: #fbfbfb;
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 4em;
}
div {
  width: 100px;
  height: 100px;
  display: grid;
  place-items: center;
  background-image: linear-gradient(yellow, orange);
  font-family: system-ui;
  font-weight: bold;
  text-transform: uppercase;
  letter-spacing: 2px;
  border-radius: 4px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
}
.image {
  cursor: url("https://pics.freeicons.io/uploads/icons/png/20278001131579606320-32.png"),
    auto;
}
.svg {
  cursor: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'  width='40' height='40' viewport='0 0 100 100' style='fill:black;font-size:22px;'><text y='50%'>?</text></svg>"),
    auto;
}

scroll-behavior

Właściwość scroll-behavior ustawiona na smooth ułatwia implementację płynnego przewijania pomiędzy sekcjami strony:

<nav>
  <h3>Scroll to</h3>
  <a href="#a">A</a>
  <a href="#b">B</a>
  <a href="#c">C</a>
</nav>
<section id="a">
  <h3>A</h3>
</section>
<section id="b">
  <h3>B</h3>
</section>
<section id="c">
  <h3>C</h3>
</section>
html {
  scroll-behavior: smooth;
}
body {
  margin: 0;
  font-family: system-ui;
  color: #fbfbfb;
}
nav {
  position: fixed;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  text-align: center;
}
h3 {
  margin: 0;
  letter-spacing: 1px;
}
a {
  text-decoration: none;
  color: inherit;
  border-bottom: 1px dashed;
}
a + a {
  margin-left: 1em;
}
section {
  width: 100%;
  height: 100vh;
  display: inline-flex;
  justify-content: center;
  align-items: center;
}
#a {
  background-color: #1266f1;
}
#b {
  background-color: #00b74a;
}
#c {
  background-color: #f93154;
}

text-overflow

Właściwość text-overflow ustawiona na ellipsis pozwala dodać ... na koniec tekstu, gdy wychodzi on poza kontener.

p {
  text-overflow: ellipsis;
}

caret-color

Właściwość caret-color ustawia kolor kursora tekstowego, widocznego znacznika (|) wskazującego gdzie zostanie wstawiony następny wpisany znak.

textarea {
  caret-color: #00b74a;
}

@supports

Reguła @supports pozwala na sprawdzenie, czy przeglądarka obsługuje określoną właściwość lub właściwości (lub kombinację właściwość/wartość) przed ich zastosowaniem.

/* check support for `grid` and `image-rendering` properties */
@supports (display: grid) {
  section {
    display: grid;
  }
}

@supports (image-rendering) {
  img {
    image-rendering: pixelated;
  }
}

var ()

Funkcja var() pozwala na użycie wartości zmiennych niestandardowych jako wartości właściwości. Drugim opcjonalnym parametrem tej funkcji jest wartość domyślna.

/* define a custom variable - the main background color */
:root {
  --primary-bg-color: #1266f1;
}

/* and use it */
button {
  background-color: var(--primary-bg-color)
}

calc ()

Funkcja calc() jest używana do określenia obliczonej wartości właściwości, które jako wartości używają rozmiaru, kąta, czasu lub liczby. Umożliwia to ustawienie wartości na podstawie dodawania lub odejmowania różnych jednostek.

Zazwyczaj element pozycjonowany bezwzględnie jest wyrównany poziomo i pionowo w następujący sposób:

.modal {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}


Jeśli znamy wymiary takiego elementu, możemy wykonać następujące czynności:

/* let's say an element has a height of 100px and a width of 200px */
.modal {
  position: absolute;
  top: calc(50% - 50px);
  left: calc(50% - 100px);
}

attr ()

Za pomocą funkcji attr() możesz pobrać wartość atrybutu wybranego elementu i użyć go w stylach.

Tworzenie dymek za pomocą CSS:

<p>Some <span data-tooltip="tooltip">text</span> here</p>
p {
  margin: 2em;
  font-size: 1.25rem;
}
span {
  color: #1266f1;
  border-bottom: 1px dashed;
  position: relative;
  cursor: pointer;
}
span::after {
  /*  ---  */
  content: attr(data-tooltip);
  /*  ---  */
  position: absolute;
  top: -1.25em;
  left: 50%;
  transform: translateX(-50%);
  color: #00b74a;
  font-style: italic;
  opacity: 0;
  transition: 0.2s;
}
span:hover::after {
  opacity: 1;
}

:target

Pseudo-klasa :target pozwala na tworzenie modali, które działają bez JavaScriptu:

<a href="#modal" class="link">Show modal</a>

<div class="modal" id="modal">
  <div class="overlay">
    <div class="content">
      <h3>Title</h3>
      <p>Description</p>
      <a href="#" class="close">✖</a>
    </div>
  </div>
</div>
@import url("https://fonts.googleapis.com/css2?family=Montserrat&display=swap");
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: "Montserrat", sans-serif;
}
a {
  text-decoration: none;
}
.link {
  display: block;
  text-align: center;
  margin-top: 1em;
}
/* --- */
.modal {
  opacity: 0;
  visibility: hidden;
  transition: 0.3s ease-in;
}
.modal:target {
  opacity: 1;
  visibility: visible;
}
/* --- */
.overlay {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  background-color: rgba(0, 0, 0, 0.25);
  display: grid;
  place-items: center;
}
.content {
  width: 320px;
  padding: 1em 0;
  background-color: #fbfbfb;
  border-radius: 2px;
  text-align: center;
  color: #262626;
  position: relative;
}
.content > *:not(.close) {
  margin: 1em 0;
}
.close {
  position: absolute;
  top: 5px;
  right: 10px;
  color: #f93154;
}

::marker

Zwykle usuwaliśmy znaczniki listy za pomocą list-style: none i dodawaliśmy własne za pomocą pseudoelementów ::before lub ::after.  Teraz jest łatwiejszy sposób, aby to zrobić - możemy użyć pseudoelementu ::marker.

<ul>
  <li>Prima</li>
  <li>Altera</li>
  <li>Triera</li>
</ul>
li::marker {
  content: "✔ ";
  color: green;
}
li:last-child::marker {
  content: "✖ ";
  color: red;
}

::selection

Pseudoelement ::selection pozwala na stylizację zaznaczonego tekstu.

p::selection {
  background-color: #262626;
  color: #fbfbfb;
}


Dziękuję za poświęcony czas i dobrego dnia!



Oryginał tekstu w języku angielskim znajdziesz tutaj.

<p>Loading...</p>