jgthms / bulma

Modern CSS framework based on Flexbox
https://bulma.io
MIT License
49.33k stars 3.96k forks source link

Tough question regarding image ratios and blocks for spacing #3444

Open nickelswitte opened 2 years ago

nickelswitte commented 2 years ago

This is about Bulma. This is a question

Overview of the problem

This is about the Bulma CSS framework

I'm using Bulma version 0.9.3 My browser is: Firefox 94.0.1 (64-Bit)

Description

Short: I need to find image ratios, where one big image has the same height, like two small ones with a block spacing in between.

Longer Version

I am programming an image blog with a gallery, looking e.g. like this: grafik

For this I am using card, block and column elements. For the top row, I use code like this:

<div class="columns">
    <div class="column">
        <div class="block">
            <div class="card">
                <div class="card-image">
                    <figure class="image is-square">
                        <a href="<%= it.image_1_full %>">
                            <img src="<%= it.image_1_full %>" alt="Placeholder image">
                        </a>
                    </figure>
                </div>
            </div>
        </div>

    </div>
    <div class="column">
        <div class="block">
            <div class="card">
                <div class="card-image">
                    <figure class="image is-square">
                        <a href="<%= it.image_2_full %>">
                            <img src="<%= it.image_2_full %>" alt="Placeholder image">
                        </a>
                    </figure>
                </div>
            </div>
        </div>
    </div>
</div>

This will all work fine, until I combine two images next to one big one like so: grafik

As you can see, the spacing introduced by the block variable will make the two right images taller in height than the left big image. No matter what ratios I am using, they never end up aligning perfectly. Even if I found a perfect ratio, is it correct that the rem used by block for spacing might screw up my layout on different devices anyway?

The code I use is the following:

<div class="columns">
    <div class="column is-two-thirds">
        <div class="block">
            <div class="card">
                <div class="card-image">
                    <figure class="image is-3by2">
                        <a href="<%= it.image_1_full %>">
                            <img src="<%= it.image_1_full %>" alt="Placeholder image">
                        </a>
                    </figure>
                </div>
            </div>
        </div>
    </div>

    <div class="column">
        <div class="block">
            <div class="card">
                <div class="card-image">
                    <figure class="image is-3by2">
                        <a href="<%= it.image_2_full %>">
                            <img src="<%= it.image_2_thumb %>" alt="Placeholder image">
                        </a>
                    </figure>
                </div>
            </div>
        </div>

        <div class="card">
            <div class="card-image">
                <figure class="image is-3by2">
                    <a href="<%= it.image_3_full %>">
                        <img src="<%= it.image_3_thumb %>" alt="Placeholder image">
                    </a>
                </figure>
            </div>
        </div>
    </div>
</div>

My questions:

  1. Is this problem solvable, when using block with rem as spacing?
  2. How can I create custom ratios to perfectly compensate for the spacing in between and is there a way to calculate these ratios?
  3. What would the smart approach be?

Steps to Reproduce

See above

Expected behavior

Find image ratios with normal block spacing, which do not create offsets like in the images above

Actual behavior

The block spacing introduces an offset, which looks bad

jgthms commented 2 years ago

I think you can play around with the spacing. You can roughly achieve something like this:

image

What you need is height of left image to equal 2 * height of right image + gap. So the variable you have to play with is the width of the left image while maintaining the ratio you want.

In any case, I would probably use CSS Grid for this. There is grid-gap for the gap, and then play with grid-template-columns to define the columns you need.

nickelswitte commented 2 years ago

Hello Jeremy, thanks for the super quick response. I appreciate that.

When I play with the width of the left image, it will change the position of the gap between the left image and the two right images, right? This would be unfavourable, as it would break the nice line which is created with the above images, like shown here: grafik

Or am I understanding something wrong? Dont I need to play with the height of both the right images?

Maybe something like this

height_left_image = height_right_image * 2 + gap

leading to:
(height_left_image - gap) / 2 = height_right_image
jgthms commented 2 years ago

If you want to align everything to the grid, the large image can not have the same ratio as the other images. Let me explain.

You have a grid with predefined cells. Each cell has a ratio of 1.66666 in this example. Here's how it looks:

image

Now, if you want a large image to cover 2 columns and 2 rows, this is what it would look like:

image

As you can see, the large image is perfectly aligned to the grid. However, this means the large image can not have the same ratio as the other cells. Why? It's because the large image has to cover the grid gap as well, so it means its height is 2 * cell height + gap and its width is 2 * cell width + gap. This messes up the ratio: it goes from 1.6666 to 1.60.

The only way for this to work, is to have zero gap:

image

Because in that case, the large image has exactly twice the height and twice the width of a cell. And because both width and height are multiplied by 2, the ratio stays the same.

I've done grids like this before, and what I do is to preserve the alignment with the grid, and allow the ratio of the large image to be slightly different. Or have no gap between the cells.

nickelswitte commented 2 years ago

Wow, thanks for the in-depth reply. This is insightful. As I am still a starter in web dev, I currently do not know how to implement your advice from the last paragraph. I definitely want to keep the gap, so how do I change the ratio of the large image just slightly (and responsively for all devices)?

Can you point me to the right article or keywords, so I can research this topic?

jgthms commented 2 years ago

Here's how you would do it with CSS Grid: https://codepen.io/jgthms/pen/NWvLvza?editors=1100

The grid has 3 columns of 300px wide, and a gap of 30px. You can see each "normal" cell has an image of 300x180, but the large one is 630x390 because it covers 2 columns and 2 rows.

Feel free to use and improve (Retina images, responsiveness…).

Also, Flickr has this tool for this gallery alignment: https://github.com/flickr/justified-layout