Why making images grid layout with masonry looks ugly?

Hello,
I want to make images grid layout in my Laravel 8 / alpinejs 3.8.1 / tailwindcss 2.2.2 app and
searching in net I found several possible decisions :

  1. With css styling
    Which is based on 3 custom classes masonry-3-col, masonry-2-col , break-inside and it works ok for my page including different devices :
    http://hostels4j.my-demo-apps.tk/hostels-gallery

  2. I found this masonry.desandro library, but trying to implmenent it on the same page
    I have very wierd results : Any image item is show with desined borders and shadows when mouse is over as expected, but
    grids layout
    is rather strange. I see that masonry library is applied. Please look the same url with debug key added “/1”
    http://hostels4j.my-demo-apps.tk/hostels-gallery/1 debug key added/missing “/1”

In Blade file below I switch these 2 modes depending on :

<div class="frontend_page_container" x-data="hostelsGalleyViewPageComponent()"
     x-init="[onHostelsGalleyViewPageComponentInit() ]" id="hostels_gallery_page_container" x-cloak>

    {{--    SOURCE : https://stackoverflow.com/questions/66914169/can-i-create-a-masonry-layout-using-tailwind-css-utility-classes--}}
    <div
        class="relative pt-16 pb-32 flex content-center items-center justify-center"
        style="min-height: 45vh;" x-cloak
    >
        <div
            class="absolute top-0 w-full h-full bg-center bg-cover"
            style='background-image: url("{{ \App\Library\Services\AppContent::BG_IMAGE_HEADER_HOSTEL }}");'
        >
          <span
              id="blackOverlay"
              class="w-full h-full absolute opacity-50 bg-black"
          ></span>
        </div>
        <div class="container relative mx-auto">
            <div class="items-center flex flex-wrap">
                <div class="w-full lg:w-6/12 px-4 ml-auto mr-auto text-center">
                    <div class="pr-12">
                        <h1 class="frontend_main_inverted_color font-semibold text-4xl">
                            {{ $site_name }}
                        </h1>

                        @if(!empty($appHeaderBlockHeader['text']))
                            <p class="mt-4 text-lg frontend_main_inverted_color">
                                {!! $appHeaderBlockHeader['text'] !!}
                            </p>
                        @endif

                        <a href="{{ route('personal.new-hostel') }}" class="btn_frontend_action_big">
                            Publish Hostel
                        </a>
                    </div>
                </div>
            </div>
        </div>

        <div
            class="top-auto bottom-0 left-0 right-0 w-full absolute pointer-events-none overflow-hidden"
            style="height: 70px;"
        >
            <svg
                class="absolute bottom-0 overflow-hidden"
                xmlns="http://www.w3.org/2000/svg"
                preserveAspectRatio="none"
                version="1.1"
                viewBox="0 0 2560 100"
                x="0"
                y="0"
            >
                <polygon
                    class="text-gray-700"
                    points="2560 0 2560 100 0 100"
                ></polygon>
            </svg>
        </div>
    </div>


    <section class="pb-20 bg-gray-300 -mt-24">
        <div class="container mx-auto px-4">


            <div class="flex flex-wrap items-center mt-16">
                @if(!empty($ourCompanyInfoBlock['name']) and !empty($ourCompanyInfoBlock['text']))
                    <div class="w-full md:w-6/12 px-2 mr-auto ml-auto">
                        <h3 class="text-3xl mb-2 frontend_content_text leading-normal">
                            {!! showAppIcon('our_company', 'frontend') !!}
                            {!! $ourCompanyInfoBlock['name'] !!}
                        </h3>
                        <p
                            class="text-lg font-light leading-relaxed mt-4 mb-4 frontend_content_text"
                        >
                            {!! $ourCompanyInfoBlock['text'] !!}
                        </p>
                    </div>
                @endif

                <div class="w-full md:w-5/12 px-2 mr-auto ml-auto">
                    <div
                        class="relative flex flex-col min-w-0 break-words bg-white w-full mb-6 shadow-lg rounded-lg bg-green-600"
                    >
                        <img
                            alt="..."
                            src="{{ \App\Library\Services\AppContent::BG_IMAGE_HOSTELS_GALLERY }}"
                            class="w-full align-middle rounded-t-lg"
                        />
                        <blockquote class="relative p-2 lg:p-6 mb-4">
                            <svg
                                preserveAspectRatio="none"
                                xmlns="http://www.w3.org/2000/svg"
                                viewBox="0 0 583 95"
                                class="absolute left-0 w-full block"
                                style="height: 95px; top: -94px;"
                            >
                                <polygon
                                    points="-30,95 583,95 583,65"
                                    class="text-green-600 fill-current"
                                ></polygon>
                            </svg>

                            <h4 class="text-xl font-bold frontend_main_inverted_color">
                                {!! $hostelsGalleryInfoBlock['name'] !!}
                            </h4>
                            @if(!empty($hostelsGalleryInfoBlock['text']))
                                <p class="text-md font-light mt-2 frontend_main_inverted_color">
                                    {!! $hostelsGalleryInfoBlock['text'] !!}
                                </p>
                            @endif

                        </blockquote>
                    </div>
                </div>
            </div>
        </div>
    </section>

    <section class="relative py-10">
        <div
            class="bottom-auto top-0 left-0 right-0 w-full absolute pointer-events-none overflow-hidden -mt-20"
            style="height: 80px;"
        >
            <svg
                class="absolute bottom-0 overflow-hidden"
                xmlns="http://www.w3.org/2000/svg"
                preserveAspectRatio="none"
                version="1.1"
                viewBox="0 0 2560 100"
                x="0"
                y="0"
            >
                <polygon
                    class="bg-gray-300"
                    points="2560 0 2560 100 0 100"
                ></polygon>
            </svg>

        </div>


        <div class="container mx-auto p-0 frontend_block_border rounded-lg">

            @if(count($hostelsDataRows) == 0)
                <div class="m-2 p-2 warning_text">
                    {!! showAppIcon('warning', 'frontend') !!}
                    No hostels found !
                </div>
            @endif

            @if(count($hostelsDataRows) > 0)
                <x-h2 class="frontend_subtitle">
                    {!! showAppIcon('image') !!}
                    {{ count($hostelsDataRows) }} {{ pluralize3( count($hostelsDataRows), 'no images', 'image', 'images' ) }}
                </x-h2>


                <div id="div_photos_container_id" class="block">
                    @if($debug)
                        <div class="main_gallery__blocks">
                            <!-- HOSTELS FOREACH START -->
                            @foreach($hostelsDataRows as $nextHostel)
                                @livewire('hostel.hostel-gallery-item', ['nextHostel' => $nextHostel, 'loop_index'=>
                                $loop->index])
                        @endforeach
                        <!-- HOSTELS FOREACH END -->
                        </div>
                    @else
                        <div
                            class="md:masonry-2-col lg:masonry-3-col box-border mx-auto before:box-inherit after:box-inherit">
                            <!-- HOSTELS FOREACH START -->
                            @foreach($hostelsDataRows as $nextHostel)
                                <div class="break-inside p-4 m-0 bg-gray-100 rounded-lg">
                                    @livewire('hostel.hostel-gallery-item', ['nextHostel' => $nextHostel, 'loop_index'=>
                                    $loop->index])
                                </div>
                            @endforeach
                        <!-- HOSTELS FOREACH END -->
                        </div>
                    @endif
                </div>

            @endif
        </div>
    </section>

    @if($debug)
        <script src="https://unpkg.com/masonry-layout@4/dist/masonry.pkgd.min.js"></script>
    @endif
    <script>

        function hostelsGalleyViewPageComponent() {
            return {
                onHostelsGalleyViewPageComponentInit: function () {
                    console.log('onHostelsGalleyViewPageComponentInit $debug::')
                    console.log('{{ $debug }}')


                    if ('{{ $debug }}' == '1') {
                        var container = document.querySelector('.main_gallery__blocks');
                        var msnry = new Masonry(container, {
                            columnWidth: 240,
                            // isFitWidth: true,
                            itemSelector: '.main_gallery__block',
                        });

                        setTimeout(setPhotosContainerHeight, 1000);  // But this method really helped
                    }

                },

            }
        } // function hostelsGalleyViewPageComponent() {

        function setPhotosContainerHeight() {
            console.log('setPhotosContainerHeight::')
            document.getElementById('div_photos_container_id').setAttribute("style", "height:100% !important");
            console.log('document.getElementById(div_photos_container_id).setAttribute("style"::')
            console.log(document.getElementById('div_photos_container_id').getAttribute("style"))

            // this.is_photos_container_loaded = true;
        }

    </script>

    <style>

        .main_gallery__blocks {
            display: -webkit-box;
            display: -ms-flexbox;
            display: flex;
            -webkit-box-align: start;
            -ms-flex-align: start;
            align-items: flex-start;
            -webkit-box-pack: start;
            -ms-flex-pack: start;
            justify-content: flex-start;
            -ms-flex-wrap: wrap;
            flex-wrap: wrap;
            width: calc(100% + 14px);
            margin: -7px;
        }

        .main_gallery__block {
            width: 100%;
            padding: 4px;
        }

        .main_gallery__link {
            width: 100%;
            height: 100%;
            position: absolute;
            top: 0;
            left: 0;
            opacity: 0;
            z-index: 2;
        }

        .main_gallery__content {
            width: 100%;
            height: 100%;
            position: relative;
        }

        .main_gallery__content img {
            width: 100%;
            height: 100%;
            -o-object-fit: cover;
            object-fit: cover;
        }

        .main_gallery__content:before {
            content: '';
            position: absolute;
            left: 0;
            top: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.4);
            opacity: 0;
            -webkit-transition: 0.3s opacity;
            -o-transition: 0.3s opacity;
            transition: 0.3s opacity;
        }

        .main_gallery__content:hover:before {
            opacity: 1;
        }

        .main_gallery__content:hover .main_gallery__info,
        .main_gallery__content:hover .main_gallery__comments,
        .main_gallery__content:hover .main_gallery__description,
        .main_gallery__content:hover .main_gallery__sticker_mark {
            opacity: 1;
        }

        .main_gallery__content:hover .main_gallery__description {
            color: #FFD846;
        }

        .main_gallery__description {
            display: block;
            width: 100%;
            font-weight: 500;
            font-size: 18px;
            letter-spacing: 0.03em;
            color: #fff;
            padding: 0 0 11px 23px;
            position: absolute;
            left: 0;
            bottom: 0;
            -webkit-transition: 0.3s color;
            -o-transition: 0.3s color;
            transition: 0.3s color;
        }

        .main_gallery__content:hover .main_gallery__description,
        .main_gallery__content:hover .main_gallery__sticker_mark {
            opacity: 1;
        }

        .main_gallery__content:hover .main_gallery__description {
            color: #FFD846;
        }

        @media screen and (max-width: 767px) {
            .main_gallery__description {
                font-size: 14px;
                padding: 0 0 15px 15px;
            }
        }

        @media screen and (max-width: 480px) {
            .main_gallery__description {
                font-size: 12px;
                padding: 0 0 10px 10px;
            }
        }


    </style>

</div>

and resources/views/livewire/hostel/hostel-gallery-item.blade.php with template for any image :

<div>

    <div class="main_gallery__block" >
        <div class="main_gallery__content">
            <a href="{{ route('hostel-view-page', $nextHostel->slug ) }}" class="main_gallery__link"></a>

            @if(!empty($nextHostel['filenameData']))
                <img src="{{$nextHostel['filenameData']['image_url']}}" alt="">
            @else
                <img src="/img/hostels-gallery.jpg" alt="{{ $nextHostel['name'] }}">
            @endif
            <p class="main_gallery__description">{{$nextHostel['id']}}::{{$nextHostel['name']}}</p>

        </div>
    </div>
</div>

Actually I would prefer to use the second way, as I want to master this library, but why results are some ugly and how it can be fixed?

Thanks!

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.