Auto-sizing element to fit inside flexbox

valyouw

Yuval

Posted on March 13, 2021

Auto-sizing element to fit inside flexbox

Intro

We have given a task to build a screen, for mobile devices, which is a single column, with a header, text, image and an action button. The "catch" is that all elements must fit into the screen with NO scrolling, where the image is the "responsive" element that should shrink/expand according to available space.

Here is a schema of the design on 2 different screens:
Alt Text

What we should note here:

  1. The image shrinks on the small device so the "GO" button is not "pushed" out of the screen
  2. On larger screens the "GO" button is adjacent to the image, and the image takes the entire width available.
  3. IMPORTANT: We are guaranteed that the text won't be too long (so there will always be some space left for the image) and we should support "portrait only".

Initial Layout

The first implementation direction that comes to mind is using a "flex" column design, this is the html structure:

<div class="box">
    <div class="title">
        This is some long header?
    </div>
    <div class="text">
        Lorem ipsum dolor sit amet...
    </div>
    <img src="https://via.placeholder.com/600x400.png">
    <button>Open</button>
</div>
Enter fullscreen mode Exit fullscreen mode

our container class, box, is a flex column:

<style>
    .box {
        display: flex;
        flex-direction: column;
        width: 100%;
        height: 100%;
        padding: 10px;
        box-sizing: border-box;
    }
</style>
Enter fullscreen mode Exit fullscreen mode

Inside our "column" we have 4 items: title, text, image and button. The title, text and button just render "as-is" taking as much space as needed, where the <img> will have to adjust to the remaining space.

Currently the result looks as follow, "small" device on the left, "large" device on the right:
Alt Text

Sizing inside flex

The first issue that we see is the <button>, which stretches to fill the entire width, this is the default behavior of elements inside a flex container, to fix this we can just apply align-self: center to the <button>, we'll apply this also to the <img>, and voila:
Alt Text

OK, while the <button> is now centered and not stretched anymore, the <img> has lost its bounds... well this can easily be fixed by specifying max-width: 100% on the <img>:
Alt Text

Now we are really close to achieving our goal, we just need to tell the image: "don't push", and the/one way to do it inside a flex container is by setting overflow: auto on the misbehaving element, at this point we'll also set some margin-top to the <button> and <img>:

<style>
    .box img {
        align-self: center;
        max-width: 100%;
        overflow: auto; /* do NOT push others*/
        margin-top: 10px;
    }

    .box button {
        align-self: center;
        margin-top: 30px;
    }
</style>
Enter fullscreen mode Exit fullscreen mode

Alt Text

The END

The key takeaways, inside flex container:

  1. Use align-self to prevent from an element to stretch.
  2. Use overflow: auto to prevent from an element to "push" other elements (assuming of course the element is "allowed" to shrink).
๐Ÿ’– ๐Ÿ’ช ๐Ÿ™… ๐Ÿšฉ
valyouw
Yuval

Posted on March 13, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

Flip Card on Hover in CSS
codepen Flip Card on Hover in CSS

November 27, 2024

I am kaustubh kulkarni
webdev I am kaustubh kulkarni

October 27, 2024

UI Verse
react UI Verse

October 18, 2024

ยฉ TheLazy.dev

About