Alternatywna propozycja zabudowy CSS

Zespół Chrome chętnie zobaczy implementację układów typu masonry w internecie. Uważamy jednak, że wdrożenie go w ramach specyfikacji CSS Grid zgodnie z zaleceniami przedstawionymi w niedawnym poście na temat WebKit byłoby błędem. Uważamy też, że post na temat WebKit odnosił się do wersji układu, której nikt nie proponował.

W tym poście chcemy wyjaśnić, dlaczego w Chrome mamy wątpliwości co do implementacji masonry w ramach specyfikacji CSS Grid Layout, oraz dokładnie opisać, co umożliwia nasza alternatywna propozycja. Krótko mówiąc:

  • Zespół Chrome bardzo chce odblokować układ typu masonry, ponieważ wie, że jest on pożądany wśród deweloperów.
  • Dodanie muru do specyfikacji siatki jest problematyczne z powodów innych niż to, czy uważasz, że mur jest siatką.
  • Definiowanie układu typu masonry poza specyfikacją siatki nie uniemożliwia stosowania różnych rozmiarów ścieżek w układzie typu masonry ani korzystania z takich właściwości jak wyrównanie czy odstępy, ani żadnych innych funkcji używanych w układzie siatki.

Czy układ typu masonry powinien być częścią siatki?

Zespół Chrome uważa, że układ mozaikowy powinien być oddzielną metodą układania, zdefiniowaną za pomocą atrybutu display: masonry (lub innego słowa kluczowego, jeśli zostanie wybrana lepsza nazwa). W dalszej części tego artykułu znajdziesz kilka przykładów tego, jak może wyglądać kod.

Istnieją 2 powiązane ze sobą powody, dla których uważamy, że układ nieregularny jest lepiej zdefiniowany poza układem kratowym: potencjalne problemy ze skutecznością układu oraz fakt, że zarówno układ nieregularny, jak i kratowy mają funkcje, które mają sens w jednej metodzie układu, ale nie w innej.

Wyniki

Siatka i masonry są odwrotne pod względem sposobu, w jaki przeglądarka obsługuje rozmiary i rozmieszczenie. Gdy układ siatki jest już gotowy, wszystkie elementy są umieszczane przed układem, a przeglądarka dokładnie wie, co znajduje się na poszczególnych ścieżkach. Umożliwia to złożone dopasowywanie, które jest bardzo przydatne w przypadku siatki. W przypadku układu typu „kamień polny” elementy są umieszczane w układzie, a przeglądarka nie wie, ile ich jest na każdym utworze. Nie jest to problem w przypadku wszystkich ścieżek o rozmiarze domyślnym lub wszystkich ścieżek o rozmiarze stałym, ale jest to problem, jeśli mieszasz ścieżki o rozmiarze stałym i domyślnym. Aby rozwiązać ten problem, przeglądarka musi najpierw rozmieścić każdy element na wiele możliwych sposobów, aby uzyskać pomiary. W przypadku dużej siatki może to spowodować problemy z wydajnością układu.

Dlatego jeśli masz układ typu masonry z definicją ścieżki grid-template-columns: 200px auto 200px (co jest bardzo częstym rozwiązaniem w przypadku siatki), zaczniesz mieć problemy. Po dodaniu siatek podrzędnych te problemy nasilają się wykładniczo.

Można argumentować, że większość użytkowników nie napotka tego problemu, ale wiemy, że użytkownicy mają bardzo duże siatki. Nie chcemy udostępniać czegoś, co ma ograniczenia dotyczące sposobu użycia, jeśli istnieje inna metoda.

Co zrobić z elementami, które nie pasują do żadnej z metod układu?

Gdy flexbox i grid stały się częścią CSS, programiści często uważali, że zachowują się one w niespójny sposób. Ta niespójność była spowodowana długotrwałymi założeniami dotyczącymi działania układu na podstawie układu blokowego. Z czasem deweloperzy zaczęli rozumieć konteksty formatowania. Gdy przełączysz się na kontekst formatowania siatki lub flex, niektóre rzeczy będą działać inaczej. Wiesz na przykład, że w modelu flexbox nie wszystkie metody wyrównania są dostępne, ponieważ flexbox jest jednowymiarowy.

Połączenie obrazu po stronie klienta z siatką powoduje zerwanie wyraźnego związku między kontekstem formatowania a dostępnością takich właściwości jak właściwości wyrównania, które są zdefiniowane w specyfikacji wyrównania elementu w ramach kontekstu formatowania.

Jeśli zdecydujemy się rozwiązać problem z wydajnością, o którym pisaliśmy wcześniej, przez zablokowanie w tle mieszanych definicji ścieżek zdefiniowanych na podstawie wewnętrznych i stałych ścieżek w przypadku układu typu masonry, pamiętaj, że bardzo popularny wzór dla układów siatki nie działa w przypadku układu typu masonry.

Istnieją też wzory, które mają sens w przypadku muru, na przykład grid-template-columns: repeat(auto-fill, max-content), ponieważ nie mają ograniczeń dotyczących krzyżowania, ale muszą pozostać nieprawidłowe w siatce. Poniżej znajduje się lista właściwości, które mają się zachowywać inaczej lub mieć inne prawidłowe wartości.

  • grid-template-areas: w przypadku układu typu masonry możesz określić tylko początkowy wiersz w kierunku innym niż masonry.
  • grid-template: Skrót musi uwzględniać wszystkie różnice.
  • Śledź wartości rozmiarów w przypadku atrybutów grid-template-columnsgrid-template-rows ze względu na różnice w wartościach prawnych.
  • grid-auto-flow nie dotyczy układu typu „pełna tablica”, a masonry-auto-flow nie dotyczy siatki. Ich połączenie mogłoby spowodować problemy z elementami, które są nieprawidłowe z powodu używanej przez Ciebie metody układu.
  • Układ macierzowy ma 4 właściwości miejsca docelowego (grid-column-start itd.), natomiast układ typu masonry ma tylko 2 właściwości.
  • Układ osi Y może używać wszystkich 6 właściwości justify-*align-*, ale układ Masonry używa tylko podzbioru, podobnie jak element flex.

Wprowadzimy też wymóg określania, co dzieje się we wszystkich nowych przypadkach błędów spowodowanych przez deweloperów, którzy używają wartości nieprawidłowej w układzie kratowym z użyciem masonry lub bez niego. Na przykład można użyć właściwości grid-template-columns: masonry lub grid-template-rows: masonry, ale nie obu naraz. Co się stanie, jeśli użyjesz obu naraz? Te informacje muszą być określone, aby wszystkie przeglądarki działały tak samo.

Wszystko to staje się skomplikowane z punktu widzenia specyfikacji, teraz i w przyszłości. Musimy się upewnić, że wszystko jest dostosowane do układu ścienkowego i czy działa w takim układzie. Jest to też mylące z perspektywy deweloperów. Dlaczego warto pamiętać, że pomimo display: grid niektóre rzeczy nie działają z powodu stosowania układu typu masonry?

alternatywną propozycję,

Jak już wspomnieliśmy, zespół Chrome chce zdefiniować układ typu masonry poza specyfikacją siatki. Nie oznacza to, że będzie ona ograniczona do bardzo prostej metody układu z identycznymi rozmiarami kolumn. Wszystkie demonstracje w poście WebKit będą nadal możliwe.

Klasyczny układ typu masonry

Gdy większość osób myśli o masonerii, ma na myśli układ z wieloma kolumnami o jednakowej wielkości. Zostanie on zdefiniowany za pomocą tego kodu CSS, który wymaga mniej linii kodu niż odpowiednia wersja z pakietu grid.

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(auto-fill, minmax(14rem, 1fr));
  gap: 1rem;
}

ścieżki o takim samym rozmiarze.

Używanie rozmiarów ścieżek typu siatka dla różnych szerokości kolumn

Poza wspomnianym wcześniej problemem z mieszanym rozmiarem ścieżki wewnętrznej i statycznym możesz używać wszystkich rozmiarów ścieżki, które lubisz z siatki. Przykład z postu na blogu WebKit, w którym pokazano wzór powtarzających się wąskich i szerszych kolumn.

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(auto-fill, minmax(8rem, 1fr) minmax(16rem, 2fr)) minmax(8rem, 1fr);
  gap: 1rem;
}

Wzór szerokich i wąskich ścieżek.

Dodatkowe rozmiary ścieżki dla układu typu masonry

Istnieją dodatkowe opcje rozmiaru ścieżki, których nie zezwalamy na użyciu w siatce, ponieważ jest to metoda układu dwuwymiarowego. Te opcje byłyby przydatne w przypadku układu typu masonry, ale ich brak w układzie kratowym mógłby być mylący.

automatyczne wypełnianie ścieżek o rozmiarze max-content.

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(auto-fill, max-content);
  gap: 1rem;
}

automatyczne wypełnianie ścieżek o rozmiarze auto, które tworzy ścieżki o tym samym rozmiarze, automatycznie dopasowując je do największej ścieżki;

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(auto-fill, auto);
  gap: 1rem;
}

Układ z automatycznym dopasowywaniem rozmiaru ścieżek.

Zezwalanie na rozciąganie treści na kilka kolumn i umieszczanie elementów w układzie typu „płytka”

Nie ma powodu, dla którego treści nie powinny zajmować kolumn w ramach osobnej specyfikacji typu masonry. Możesz użyć właściwości masonry-track, która jest skrótem właściwości masonry-track-startmasonry-track-end, ponieważ w układzie typu masonry masz tylko 1 wymiar, na którym możesz się skupić.

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(auto-fill, auto);
}

.span-2 {
  masonry-track: span 2; /* spans two columns */
}

.placed {
  masonry-track: 2 / 5; /* covers tracks 2, 3, and 4 */
}

Układ typu „masonry” z umieszczonymi i rozpiętymi elementami.

Podwójne ścieżki lub ścieżki w ramach podwójnej siatki, które przyjmują ścieżki w ramach ścieżek.

Można to obsługiwać za pomocą osobnej specyfikacji typu masonry, z tym zastrzeżeniem, że nie można mieszać ścieżek o rozmiarach bezwzględnych i stałych. Należy określić, jak dokładnie ma to wyglądać. Nie widzimy powodu, dla którego nie miałoby to działać.

Podsumowanie

Chcielibyśmy dojść do punktu, w którym specyfikacja będzie mogła być wysyłana w ramach interoperacyjności. Chcemy jednak, aby było to rozwiązanie, które działa dobrze teraz i w przyszłości oraz na które deweloperzy mogą polegać. Jedynym sposobem na rozwiązanie opisanych problemów ze skutecznością byłoby pogorszenie drugiego problemu, czyli posiadania elementów siatki niedozwolonych w masonerii. Nie jest to dobre rozwiązanie, zwłaszcza że można mieć wszystkie funkcje siatki, które są potrzebne, zachowując przy tym wyraźne rozróżnienie między różnymi elementami.

Jeśli chcesz podzielić się opinią, dołącz do dyskusji w problemie 9041.

Dziękujemy Bramusowi, Tab Atkins-Bittnerowi, Una Kravets, Ianowi Kilpatrickowi i Chrisowi Harrelsonowi za sprawdzenie tego posta i dyskusje, które do niego doprowadziły.