Flex Item Expanded Beyond Flex Container

Updated:


When I created an online live code editor (there will be another post about that), it consisted of <textarea> and <iframe>, where text areas are for users typing the HTML and CSS while <iframe> is showing the live output. HTML and CSS boxes are stacked on top of each other, taking up half of the screen on the left, and output takes up another half of the screen on the right.

I want it to look like the image below.

What a live editor is supposed to look like

Problem

But it first looks like the image below. The output box on the right seems to extend longer than the code boxes on the left.

Unaligned boxes

Here is my initial structure.

<div class="flex-container">
    <div class="code-block">
        <label for="html">HTML</label>
        <textarea rows="10"></textarea>


        <label for="html">CSS</label>
        <textarea rows="10"></textarea>
    </div>

    <div class="output">
        <label for="output">Output</label>
        <div class="frame">
            <iframe></iframe>
        </div>
    </div>
</div>
.flex-container {
    display: flex;
    gap: 1rem;
}

.code-block {
    height: 100%;
    width: 100%;
}

.output {
    width: 100%;
}

label {
    display: block
}

textarea {
    width: 100%;
    border: 1px black solid;
}

.frame {
    border: 1px black solid;
    height: 100%;
}

This structure resulted in the output box on the right expanding beyond the flex container, as you can see using the Devtool to inspect the element. The purple box is where the flex container is.

Using devtool to inpsect flex container

We learn that flex items should be the same height but why is one longer than the other?

If we carefully look at the HTML structure, <div class="flex-container"> is a flex container and its children are flex items, which are <div class="code-block"> and <div class="output">. This matches what the devtool shows us in a purple box.

The iframe is nested inside the <div class="frame"> and <div class="output"> where <div class="output"> is a flex item but its descendant isn’t. Therefore, the rule of equal height of flex items doesn’t apply to the <iframe>.

Solution

  1. Flatten HTML structure

We have to change the HTML structure by removing <div class="frame"> and adding CSS class frame on the iframe element instead.

<div class="output">
    <label for="output">Output</label>
    <iframe class="frame"></iframe>
</div>
.frame {
  border: 1px black solid;
  height: 100%;
  width: 100%;
}

The output box isn’t still aligned with the <div class="code-block"> because, as mentioned earlier, the descendants of a flex item aren’t flex items themselves. That would lead to the next fix.

  1. Make a flex item a flex container

To make the descendants of the flex items, in our case, <div class="code-block"> and <div class="output">, behave like flex items; we need to make those flex containers.

.code-block {
  height: 100%;
  width: 100%;
  display: flex;
  flex-direction: column;
}

.output {
  width: 100%;
  display: flex;
  flex-direction: column;
}

By adding display: flex; to both classes of code-block and output, we make them flex containers and their descendants are now flex items. Because we set the iframe height to 100%, it now expands to fill the container.

Aligned boxes inspected

Now we got the aligned code editor!

Sidenote:

If we want to make it more of a flex way, instead of defining height: 100%; to class frame, we can use flexbox properties instead.

.frame {
    border: 1px black solid;
    flex: 1;
    width: 100%;
}

This is a shorthand for flex: 1 1 0% (Flex-grow, flex-shrink, flex-basis).

It tells that flex item to grow as it needs. When applying only 1 value (in the example above, we only applied flex-grow), the rest of the values are set to their default values.

Tags: