Ta odpowiedź ma dwie główne sekcje:
- Zrozumienie, jak działa wyrównanie w siatce CSS.
- Sześć metod wyśrodkowania w siatce CSS.
Jeśli interesują Cię tylko rozwiązania, pomiń pierwszą sekcję.
Struktura i zakres układu siatki
Aby w pełni zrozumieć, jak działa centrowanie w kontenerze siatki, ważne jest, aby najpierw zrozumieć strukturę i zakres układu siatki.
HTML konstrukcja kontenera siatki ma trzy poziomy:
Każdy z tych poziomów jest niezależny od pozostałych pod względem zastosowania właściwości siatki.
Zakres kontenera sieci jest ograniczony do relacji rodzic-dziecko.
Oznacza to, że kontener siatki jest zawsze elementem nadrzędnym, a element siatki jest zawsze elementem podrzędnym. Właściwości siatki działają tylko w ramach tej relacji.
Potomkowie kontenera siatki poza elementami podrzędnymi nie są częścią układu siatki i nie akceptują właściwości siatki. (Przynajmniej nie do momentu subgrid
zaimplementowania funkcji, która pozwoli potomkom elementów siatki respektować wiersze głównego kontenera).
Oto przykład opisanych powyżej koncepcji struktury i zakresu.
Wyobraź sobie kratkę przypominającą kółko i krzyżyk.
article {
display: inline-grid;
grid-template-rows: 100px 100px 100px;
grid-template-columns: 100px 100px 100px;
grid-gap: 3px;
}
Chcesz, aby X i O były wyśrodkowane w każdej komórce.
Tak więc wyśrodkowujesz na poziomie pojemnika:
article {
display: inline-grid;
grid-template-rows: 100px 100px 100px;
grid-template-columns: 100px 100px 100px;
grid-gap: 3px;
justify-items: center;
}
Ale ze względu na strukturę i zakres układu siatki, justify-items
na kontenerze wyśrodkowuje się elementy siatki, a nie treść (przynajmniej nie bezpośrednio).
article {
display: inline-grid;
grid-template-rows: 100px 100px 100px;
grid-template-columns: 100px 100px 100px;
grid-gap: 3px;
justify-items: center;
}
section {
border: 2px solid black;
font-size: 3em;
}
<article>
<section>X</section>
<section>O</section>
<section>X</section>
<section>O</section>
<section>X</section>
<section>O</section>
<section>X</section>
<section>O</section>
<section>X</section>
</article>
Ten sam problem z align-items
: Treść może być wyśrodkowana jako produkt uboczny, ale straciłeś projekt układu.
article {
display: inline-grid;
grid-template-rows: 100px 100px 100px;
grid-template-columns: 100px 100px 100px;
grid-gap: 3px;
justify-items: center;
align-items: center;
}
article {
display: inline-grid;
grid-template-rows: 100px 100px 100px;
grid-template-columns: 100px 100px 100px;
grid-gap: 3px;
justify-items: center;
align-items: center;
}
section {
border: 2px solid black;
font-size: 3em;
}
<article>
<section>X</section>
<section>O</section>
<section>X</section>
<section>O</section>
<section>X</section>
<section>O</section>
<section>X</section>
<section>O</section>
<section>X</section>
</article>
Aby wyśrodkować treść, musisz przyjąć inne podejście. Odnosząc się ponownie do struktury i zakresu układu siatki, musisz traktować element siatki jako element nadrzędny, a treść jako element podrzędny.
article {
display: inline-grid;
grid-template-rows: 100px 100px 100px;
grid-template-columns: 100px 100px 100px;
grid-gap: 3px;
}
section {
display: flex;
justify-content: center;
align-items: center;
border: 2px solid black;
font-size: 3em;
}
article {
display: inline-grid;
grid-template-rows: 100px 100px 100px;
grid-template-columns: 100px 100px 100px;
grid-gap: 3px;
}
section {
display: flex;
justify-content: center;
align-items: center;
border: 2px solid black;
font-size: 3em;
}
<article>
<section>X</section>
<section>O</section>
<section>X</section>
<section>O</section>
<section>X</section>
<section>O</section>
<section>X</section>
<section>O</section>
<section>X</section>
</article>
jsFiddle demo
Sześć metod wyśrodkowania w siatce CSS
Istnieje wiele metod wyśrodkowania elementów siatki i ich zawartości.
Oto podstawowa siatka 2x2:
grid-container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-auto-rows: 75px;
grid-gap: 10px;
}
/* can ignore styles below; decorative only */
grid-container {
background-color: lightyellow;
border: 1px solid #bbb;
padding: 10px;
}
grid-item {
background-color: lightgreen;
border: 1px solid #ccc;
}
<grid-container>
<grid-item>this text should be centered</grid-item>
<grid-item>this text should be centered</grid-item>
<grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
<grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
</grid-container>
Flexbox
Aby w prosty i łatwy sposób wyśrodkować zawartość elementów siatki, użyj flexbox.
Dokładniej, zmień element siatki w elastyczny kontener.
W przypadku tej metody nie ma konfliktu, naruszenia specyfikacji ani innego problemu. Jest czysty i ważny.
grid-item {
display: flex;
align-items: center;
justify-content: center;
}
grid-container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-auto-rows: 75px;
grid-gap: 10px;
}
grid-item {
display: flex; /* new */
align-items: center; /* new */
justify-content: center; /* new */
}
/* can ignore styles below; decorative only */
grid-container {
background-color: lightyellow;
border: 1px solid #bbb;
padding: 10px;
}
grid-item {
background-color: lightgreen;
border: 1px solid #ccc;
}
<grid-container>
<grid-item>this text should be centered</grid-item>
<grid-item>this text should be centered</grid-item>
<grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
<grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
</grid-container>
Zobacz ten post, aby uzyskać pełne wyjaśnienie:
Układ siatki
W ten sam sposób, w jaki element elastyczny może być również kontenerem elastycznym, element siatki może być również kontenerem siatki. To rozwiązanie jest podobne do powyższego rozwiązania flexbox, z tym wyjątkiem, że centrowanie jest wykonywane za pomocą właściwości grid, a nie flex.
grid-container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-auto-rows: 75px;
grid-gap: 10px;
}
grid-item {
display: grid; /* new */
align-items: center; /* new */
justify-items: center; /* new */
}
/* can ignore styles below; decorative only */
grid-container {
background-color: lightyellow;
border: 1px solid #bbb;
padding: 10px;
}
grid-item {
background-color: lightgreen;
border: 1px solid #ccc;
}
<grid-container>
<grid-item>this text should be centered</grid-item>
<grid-item>this text should be centered</grid-item>
<grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
<grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
</grid-container>
auto
marginesy
Służy margin: auto
do wyśrodkowywania elementów siatki w pionie i poziomie.
grid-item {
margin: auto;
}
grid-container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-auto-rows: 75px;
grid-gap: 10px;
}
grid-item {
margin: auto;
}
/* can ignore styles below; decorative only */
grid-container {
background-color: lightyellow;
border: 1px solid #bbb;
padding: 10px;
}
grid-item {
background-color: lightgreen;
border: 1px solid #ccc;
}
<grid-container>
<grid-item>this text should be centered</grid-item>
<grid-item>this text should be centered</grid-item>
<grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
<grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
</grid-container>
Aby wyśrodkować zawartość elementów siatki, musisz umieścić element w kontenerze grid (lub flex), zawinąć anonimowe elementy w ich własne elementy ( ponieważ nie mogą być bezpośrednio kierowane przez CSS ) i zastosować marginesy do nowych elementów.
grid-item {
display: flex;
}
span, img {
margin: auto;
}
grid-container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-auto-rows: 75px;
grid-gap: 10px;
}
grid-item {
display: flex;
}
span, img {
margin: auto;
}
/* can ignore styles below; decorative only */
grid-container {
background-color: lightyellow;
border: 1px solid #bbb;
padding: 10px;
}
grid-item {
background-color: lightgreen;
border: 1px solid #ccc;
}
<grid-container>
<grid-item><span>this text should be centered</span></grid-item>
<grid-item><span>this text should be centered</span></grid-item>
<grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
<grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
</grid-container>
Właściwości linii trasowania skrzynki
Rozważając użycie poniższych właściwości w celu wyrównania elementów siatki, przeczytaj auto
powyższą sekcję dotyczącą marginesów.
align-items
justify-items
align-self
justify-self
https://www.w3.org/TR/css-align-3/#property-index
text-align: center
Aby wyśrodkować zawartość w poziomie w elemencie siatki, można użyć text-align
właściwości.
grid-container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-auto-rows: 75px;
grid-gap: 10px;
text-align: center; /* new */
}
/* can ignore styles below; decorative only */
grid-container {
background-color: lightyellow;
border: 1px solid #bbb;
padding: 10px;
}
grid-item {
background-color: lightgreen;
border: 1px solid #ccc;
}
<grid-container>
<grid-item>this text should be centered</grid-item>
<grid-item>this text should be centered</grid-item>
<grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
<grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
</grid-container>
Zwróć uwagę, że przy centrowaniu w pionie vertical-align: middle
nie będzie działać.
Dzieje się tak, ponieważ vertical-align
właściwość dotyczy tylko kontenerów wbudowanych i kontenerów komórek tabeli.
grid-container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-auto-rows: 75px;
grid-gap: 10px;
text-align: center; /* <--- works */
vertical-align: middle; /* <--- fails */
}
/* can ignore styles below; decorative only */
grid-container {
background-color: lightyellow;
border: 1px solid #bbb;
padding: 10px;
}
grid-item {
background-color: lightgreen;
border: 1px solid #ccc;
}
<grid-container>
<grid-item>this text should be centered</grid-item>
<grid-item>this text should be centered</grid-item>
<grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
<grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
</grid-container>
Można by powiedzieć, że display: inline-grid
ustanawia kontener na poziomie liniowym i to byłaby prawda. Dlaczego więc nie vertical-align
działa w elementach siatki?
Powodem jest to, że w kontekście formatowania siatki elementy są traktowane jako elementy blokowe.
6.1. Wyświetlanie pozycji siatki
display
Wartość elementu siatki jest blockified : jeśli określony display
o dziecko w napływ elementu generującego pojemnik siatka jest wartość inline poziomu, to oblicza się jego odpowiednik blok poziomu.
W kontekście formatowania bloków , do czego ta vertical-align
właściwość została pierwotnie zaprojektowana, przeglądarka nie oczekuje, że znajdzie element na poziomie bloku w kontenerze wbudowanym. To nieprawidłowy HTML.
Pozycjonowanie CSS
Wreszcie, istnieje ogólne rozwiązanie do centrowania CSS, które działa również w Grid: pozycjonowanie absolutne
Jest to dobra metoda wyśrodkowania obiektów, które należy usunąć z obiegu dokumentów. Na przykład, jeśli chcesz:
Po prostu ustaw position: absolute
element, który ma być wyśrodkowany, i element position: relative
nadrzędny, który będzie służył jako blok zawierający (zwykle jest to element nadrzędny). Coś takiego:
grid-item {
position: relative;
text-align: center;
}
span {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
grid-container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-auto-rows: 75px;
grid-gap: 10px;
}
grid-item {
position: relative;
text-align: center;
}
span, img {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
/* can ignore styles below; decorative only */
grid-container {
background-color: lightyellow;
border: 1px solid #bbb;
padding: 10px;
}
grid-item {
background-color: lightgreen;
border: 1px solid #ccc;
}
<grid-container>
<grid-item><span>this text should be centered</span></grid-item>
<grid-item><span>this text should be centered</span></grid-item>
<grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
<grid-item><img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt=""></grid-item>
</grid-container>
Oto pełne wyjaśnienie, jak działa ta metoda:
Oto sekcja dotycząca pozycjonowania bezwzględnego w specyfikacji Grid: