Przejdź do głównej treści
Grafika przedstawia ukryty obrazek

Układ Masonry w Bootstrap 5.3 z wykorzystaniem komponentów Card

Masonry

Czym jest układ Masonry?

Układ Masonry to technika rozmieszczania elementów w siatce o nieregularnych wysokościach, przypominająca ułożenie cegieł w murze. Jest często wykorzystywana w galeriach obrazów, blogach i innych aplikacjach internetowych prezentujących dynamiczne treści.

Wsparcie Masonry w Bootstrap 5.3

Bootstrap 5.3 nie zawiera wbudowanego wsparcia dla układu Masonry, ale możemy łatwo dodać go za pomocą biblioteki Masonry.js.

Przykładowy kod

Oto przykład implementacji układu Masonry w Bootstrap 5.3 z użyciem komponentów Card:

<!DOCTYPE html>
<html lang="pl">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Masonry w Bootstrap 5.3</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://unpkg.com/masonry-layout@4/dist/masonry.pkgd.min.js"></script>
</head>
<body>
    <div class="container mt-4">
        <div class="row" data-masonry='{"percentPosition": true }'>
            <div class="col-md-6 mb-4">
                <div class="card">
                    <img src="https://placehold.co/300x200" class="card-img-top" alt="Obraz">
                    <div class="card-body">
                        <h5 class="card-title">Tytuł 1</h5>
                        <p class="card-text">Krótki opis karty.</p>
                    </div>
                </div>
            </div>
            <div class="col-md-6 mb-4">
                <div class="card">
                    <img src="https://placehold.co/300x250" class="card-img-top" alt="Obraz">
                    <div class="card-body">
                        <h5 class="card-title">Tytuł 2</h5>
                        <p class="card-text">Inny opis karty.</p>
                    </div>
                </div>
            </div>
            <div class="col-md-6 mb-4">
                <div class="card">
                    <img src="https://placehold.co/300x180" class="card-img-top" alt="Obraz">
                    <div class="card-body">
                        <h5 class="card-title">Tytuł 3</h5>
                        <p class="card-text">Jeszcze inny opis.</p>
                    </div>
                </div>
            </div>
            <div class="col-md-6 mb-4">
                <div class="card">
                    <img src="https://placehold.co/300x250" class="card-img-top" alt="Obraz">
                    <div class="card-body">
                        <h5 class="card-title">Tytuł 2</h5>
                        <p class="card-text">Inny opis karty.</p>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <script>
        document.addEventListener('DOMContentLoaded', function() {
            var msnry = new Masonry('.row', {
                itemSelector: '.col-md-6',
                percentPosition: true
            });
        });
    </script>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

Omówienie kodu

  • Struktura HTML: Użyto klasy row dla kontenera kart oraz col-md-6 dla responsywnego układu kolumn.
  • Masonry.js: Biblioteka układu Masonry jest dodana poprzez CDN i inicjalizowana w skrypcie.
  • Karty Bootstrap: Każda karta ma nieregularne wysokości obrazków, co demonstruje dynamiczny układ Masonry.
  • Stylizacja: Klasa mb-4 zapewnia margines dolny między kartami.

Obsługa Masonry na stronie z Vue.js

W przypadku stron z treścią ładowaną dynamicznie za pomocą żądań asynchronicznych sporawa nie jest już taka prosta jak wyżej. Poniższy kod przedstawia jak zastosować Masonry w kodzie z Vue.js.

<!DOCTYPE html>
<html lang="pl">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Masonry w Bootstrap 5.3 Vue 2.7</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
    <script src="https://unpkg.com/masonry-layout@4/dist/masonry.pkgd.min.js"></script>
</head>
<body>
    <div class="container mt-4" id="app">
        <div class="row" ref="masonry">
            <div class="col-md-6 mb-4" v-for="item in items" :key="item.id">
                <div class="card">
                    <img :src="item.image" class="card-img-top" alt="Obraz">
                    <div class="card-body">
                        <h5 class="card-title">{{ item.title }}</h5>
                        <p class="card-text">{{ item.text }}</p>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.imagesloaded/4.1.4/imagesloaded.pkgd.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/masonry-layout@4.2.2/dist/masonry.pkgd.min.js" integrity="sha384-GNFwBvfVxBkLMJpYMOABq3c+d3KnQxudP/mGPkzpZSTYykLBNsZEnG2D9G/X/+7D" crossorigin="anonymous"></script>

    <script>

        var vm = new Vue({
            el: '#app',
            data: {
                items: []
            },
            updated() {
                if (!this.items.length) return

                this.$nextTick(() => {
                    this.initMasonry()
                });
            },
            methods: {
                initMasonry() {
                    const grid = this.$refs.masonry
                    if (!grid) return

                    imagesLoaded(grid, () => {
                        if (this.masonry) {
                            this.masonry.reloadItems()
                            this.masonry.layout()
                            return
                        }

                        this.masonry = new Masonry(grid, {
                            itemSelector: '.col-md-6',
                            percentPosition: true,
                            transitionDuration: 0
                        })
                    })
                }
            }
        });

        setTimeout(function() {
            vm.items = [
                {image: 'https://placehold.co/300x200', title: 'Tytuł 1', text: 'Krótki opis'},
                {image: 'https://placehold.co/300x250', title: 'Tytuł 2', text: 'Dłuższy opis, który normalnie powodowałby różnicę wysokości.'},
                {image: 'https://placehold.co/300x180', title: 'Tytuł 3', text: 'Krótki opis'},
                {image: 'https://placehold.co/300x250', title: 'Tytuł 4', text: 'Dłuższy opis, który normalnie powodowałby różnicę wysokości.'}
            ];
        }, 500);

    </script>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

Obsługa Masonry na stronie z Knockout.js

Podobie jak w przypadku Vue.js aby obsłużyć Masonry trzeba użyć podobnego podejścia, ładując dodatkową bibliotekę imagesloaded i obsłużyć Masonry w JavaScript.

<!DOCTYPE html>
<html lang="pl">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Masonry w Bootstrap 5.3 Knockout 3.5</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.5.0/knockout-min.js"></script>
    <script src="https://unpkg.com/masonry-layout@4/dist/masonry.pkgd.min.js"></script>
</head>
<body>
    <div class="container mt-4" id="app">
        <div class="row" data-masonry='{"percentPosition": true }' data-bind="foreach: items">
            <div class="col-md-6 mb-4">
                <div class="card">
                    <img data-bind="attr: {src: image}" class="card-img-top" alt="Obraz">
                    <div class="card-body">
                        <h5 class="card-title" data-bind="text: title"></h5>
                        <p class="card-text" data-bind="text: text"></p>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.imagesloaded/4.1.4/imagesloaded.pkgd.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/masonry-layout@4.2.2/dist/masonry.pkgd.min.js" integrity="sha384-GNFwBvfVxBkLMJpYMOABq3c+d3KnQxudP/mGPkzpZSTYykLBNsZEnG2D9G/X/+7D" crossorigin="anonymous"></script>

    <script>

        var vm = {
            items: ko.observableArray()
        };

        ko.applyBindings(vm);

        setTimeout(function() {
            vm.items([
                {image: 'https://placehold.co/300x200', title: 'Tytuł 1', text: 'Krótki opis'},
                {image: 'https://placehold.co/300x250', title: 'Tytuł 2', text: 'Dłuższy opis, który normalnie powodowałby różnicę wysokości.'},
                {image: 'https://placehold.co/300x180', title: 'Tytuł 3', text: 'Krótki opis'},
                {image: 'https://placehold.co/300x250', title: 'Tytuł 4', text: 'Dłuższy opis, który normalnie powodowałby różnicę wysokości.'}
            ]);

            var row = document.querySelector('.row[data-masonry]');
            if (row) {
                imagesLoaded(row, function() {
                    new Masonry(row, {
                        itemSelector: '.col-md-6',
                        percentPosition: true
                    });
                });
            }

        }, 500);

    </script>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

Dzięki temu układowi uzyskujemy estetyczne i responsywne rozmieszczenie kart w siatce o nieregularnych wysokościach. Można go dostosować do własnych potrzeb, np. zmieniając liczby kolumn czy rozmiary obrazów.

17 lutego 2025 33

Kategorie

programowanie

Dziękujemy!
()

Powiązane wpisy

Ilustracja tematu Automatyczny motyw Bootstrap 53 na bazie pory dnia
4 stycznia 2025 6 min 71

Automatyczny motyw Bootstrap 5.3 na bazie pory dnia

Czytaj więcej
Zdjecie zwiazane z Dlaczego warto zainwestowa w stron internetow na frameworku MVC
3 lutego 2025 2 min 22

Dlaczego warto zainwestować w stronę internetową na frameworku MVC?

Czytaj więcej
Zdjecie zwiazane z Kompletny przewodnik po komponentach Bootstrap 5
13 marca 2025 3 min 18

Kompletny przewodnik po komponentach Bootstrap 5

Czytaj więcej
Wymiana doświadczeń

Masz podobne doświadczenia?

Chętnie poznam Twoją perspektywę i porozmawiam o tym temacie szerzej.

Napisz do mnie

Każda perspektywa może wnieść coś wartościowego do dyskusji.

Twoja prywatność i pliki cookies

  1. Ta strona internetowa wykorzystuje wyłącznie niezbędne pliki cookies, które są wymagane do jej prawidłowego działania – m.in. do poprawnego wyświetlania treści, zapamiętania podstawowych ustawień przeglądarki oraz zapewnienia stabilności serwisu.
  2. Nie stosuję plików cookies w celach marketingowych, reklamowych ani analitycznych.
  3. Strona ma charakter wyłącznie informacyjny i nie zawiera formularzy kontaktowych, rejestracyjnych ani zakupowych, przez które dane mogłyby być przesyłane na serwer.
  4. Nie zbieram danych osobowych podczas zwykłego korzystania z witryny.
  5. Serwis nie korzysta z certyfikatu SSL, jednak ze względu na informacyjny charakter strony nie jest wymagane przesyłanie poufnych danych. Zalecam jednak, aby nigdy nie wpisywać haseł ani danych osobowych na stronach bez szyfrowanego połączenia.
  6. Korzystając z tej strony, wyrażasz zgodę na używanie wyłącznie niezbędnych plików cookies.

Więcej informacji znajdziesz w mojej polityce prywatności.