How to make a flex div contained an image without expanding beyond the image dimensions

Hi friends:
I have a Parent and a Child div.
Both are set to display flex.

I need the child div to be centered on the screen no matter the size.
However, I also need the child div to contain an image and to re-size when the image dimensions changes.

The problem is the child div fills the entire screen when I add an image.
But the div behaves exactly as needed when I us only text, meaning it hugs the text and does not stretch beyond the text size.
How do I make this work?

Here is an illustration.

@amplitude64 — I can’t quite work out what you want to see. Do you want to be able to see the child div at all, or should it just be filled with the image? If so, you really just want an image centered in the parent. So the images need some constraints — like being a certain size or percentage of the area of the container. It would be good if you could just clarify a bit more.

1 Like

@ralphm
Thanks!

I do not want to be able to see any parts of the child div except the image in it.
Also, I could have used fixed width, but the image needs to be responsive and so I cannot specify a width on the child div which contains the inline image.

Here is a code example.:
If you run this code, you will see the child div has spaces on the sides.

 <style>
    *{
      margin: 0;
      padding: 0;
        border: none;
        list-style: none;
    }
    html, body {
      min-height: 100%;
      height: 100vh;
    }

    div.wrapper{
      position: relative;
      min-height: 100%;
      height: 100vh;
      display: flex;
      flex-direction: column;
      overflow: auto;
    }

  /* parent div */
    div.content{
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        min-height: 100%;
        height: 100vh;
    }

  /* child div  */
    div.splash {
        display: flex;
        flex-direction: row;
        align-items: center;
        justify-content: center;
        position: relative;
        background: black;

  /* This works with text only. */
        width: fit-content;
        block-size: fit-content;
    }

     /* We change the image size here. */
    div.splash > img.brand {
        height: auto;
        width: 50%;
    }
  </style>
</head>
<body>
<div class="wrapper">
    <div class="content">
        <div class="splash">
            <img class="brand" src="https://i.natgeofe.com/k/75ac774d-e6c7-44fa-b787-d0e20742f797/giant-panda-eating_4x3.jpg" width="3072" height="2304" alt="logo">
        </div>
    </div>
</div>
</body>
2 Likes

It seems to me you’re using way too much code here. To achieve this, you really need far fewer elements (assuming this is all your page will do). I would also suggest using Grid layout for this. Here’s a quick knock-up of how you could do this layout:

2 Likes

It tried it with Flexbox, and I guess it’s less code (although the Grid option could have been done with a lot less code too!), so certainly a viable option:

2 Likes

If you want the image to be a natural size then don’t set a width for it (although you will still need a max-width).

e.g. Using Ralphs code above. :slight_smile:

2 Likes

@PaulOB — Much nicer!

2 Likes

Here’s a grid version with a little animation to show the effect of different sized images.

3 Likes

@PaulOB — Oh, now you’re just showing off. :stuck_out_tongue:

3 Likes

@ralphm
Thank you, my friend.
Some of that code is not relevant to this as it represents the entire page layout, but I wanted to disclose the full code so nothing is left out.

With that said, I am so excited to try out all of these samples and suggestions.

Post back soon.

Thank you, guys, so much.

1 Like

@ralphm
I am confused, I see that the article is not hugging the image when I view this in code pen.
Perhaps I am not following, or I have explained something wrongly, we see that the article tag still extends the width of the page instead of only the dimensions of the image.

Was that your intention?

I was meaning, the article tag in your code will contain the image but it will be centered as a child tag of a parent that also fills the page and is flex. But the article tag will wrap around the image and be responsive as the image dimension changes.

The article element was used in place of your original “parent div”. The real point of the demos above is to show that you don’t need any container around the image for the purposes of centering it. If there’s some other reason for having an element (div or otherwise) wrapping tightly around the image, then fair enough, but from the scenario you’ve presented us with, there’s no reason to have it there. It’s still preferable to have a wrapper set to display: flex than to use the body element, so that’s the purpose of the article. (Of course, it could have been a div, perhaps with a class, but it’s easier just to use the article element for demo porpoises.)

If there’s a larger context for this thread, then we’d need to know how this fits in with a larger layout. We’ve basically just been showing how to center an image on screen while keeping it responsive, as that’s essentially the challenge you appear to have posed here. :slight_smile:

1 Like

Rereading your first post, I’m guessing you want a centered container that can hold text or an image (or both) and still remain centered? Here’s a quick attempt at that (Paul will come up with something more bulletproof, though!):

You can switch between commenting out the image and the text to see how they both work.

Looks fine with text and image showing:

@ralphm
Sorry about the confusion:
You are right, and my apologies, I should have place this in better context as to what I am intending to do as far as the end product.

The reason I am trying to have a div hug the image is because I want to make this div position relative and then put another absolute div in it to have text on top of the image.

div 1. Wrapper
div 2. Child div containing image.
div 3. Absolute position div contain text on top of child div.

Here is a graphical example:
I will use opacity on the image so that the text is more readable.

Okay, I see the result you want, but I’m not convinced about your specifications for getting the job done. I still don’t think you need as many containers as you’re suggesting, and I would use Grid rather than positioning, as with Grid you can also place elements on top of each other. (Anyhow, I found it easier to do it with Grid than by using positioning.)

Here’s my latest demo (in lieu/hope of Paul coming up with something better!)

Of course, you could also set the image as a background image instead …

1 Like

Not better just different :slight_smile:

The image is a natural size again so not fixed to a set width and the text will follow. It could be done with less elements but I think this structure makes more sense.

1 Like

I always learn new things from your demos. I had never really cottoned on to the use of inset, and it didn’t dawn on me that you can set an element to display: grid and then use align and justify to center itself like that. :slight_smile:

1 Like

Yes it saves a bit of typing :slight_smile:

inset:0 0 0 0;

is equivalent to:

top:0;
bottom:0;
left:0;
right:0;
1 Like

…and just for completeness the slideshow version to show different size images and how they would look. :slight_smile:

1 Like

@PaulOB and @ralphm
Thank you both so much for the incredible support, knowledge and feedback.

2 Likes