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" data-masonry='{"percentPosition": true }'>
            <div class="col-md-6 mb-4" v-for="item in items">
                <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',
            updated() {
                var row = document.querySelector('.row[data-masonry]');
                if (row) {
                    imagesLoaded(row, function() {
                        new Masonry(row, {
                            itemSelector: '.col-md-6',
                            percentPosition: true
                        });
                    });
                }
            },
            data: {
                items: []
            }
        });

        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 27

Kategorie

programowanie

Dziękujemy!
()

Powiązane wpisy


Informacja o cookies

Moja strona internetowa wykorzystuje wyłącznie niezbędne pliki cookies, które są wymagane do jej prawidłowego działania. Nie używam ciasteczek w celach marketingowych ani analitycznych. Korzystając z mojej strony, wyrażasz zgodę na stosowanie tych plików. Możesz dowiedzieć się więcej w mojej polityce prywatności.