最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - All Flexbox Containers Expanding Unintentionally When Toggling One Container - Stack Overflow

programmeradmin2浏览0评论

I'm working on a layout using Flexbox, where I have multiple containers, each containing collapsible content. When I toggle the expansion/visibility of one collapsible container, all the containers expand in height, which is not the desired behavior. The content of the other boxes doesn't become visible, but their heights increase, matching the one that was toggled.

Expected behavior:
When toggling the visibility of .snippet-text-information by clicking the .snippet-button ''+'' button, only the .snippet-box containing the toggled element should adjust its height accordingly. Other .snippet-box containers should remain at their original height.

Actual behavior:
When I toggle the expansion of one .snippet-text-information element, all .snippet-box containers expand in height, even though only the content of one box is becoming visible. The height of each .snippet-box matches the expanded content of the toggled box.

Code:

    function toggleExtension() {
        const buttons = document.querySelectorAll('.snippet-button');
        buttons.forEach(button => {
            button.addEventListener('click', () => {
                const target = document.querySelector(button.getAttribute('data-target'));
                target.classList.toggle('active');
            });
        });
    }

    window.onload = toggleExtension;
.snippet-box-container {
    display: flex;
    justify-content: center;
    gap: 25px;
    width: 100%;
    padding: 0px 15px;
}

.snippet-box {
    display: flex;
    flex-direction: column;
    min-height: 180px;
    flex-basis: 290px;
    background-color: white;
    box-shadow: 0px 0px 20px rgba(128, 128, 128, 0.1);
    border-radius: 15px;
    box-sizing: border-box;
}

.snippet-button-box {
    display: flex;
    justify-content: flex-end;
}

.snippet-button {
    height: 35px;
    width: 35px;
    background-color: rgb(232, 230, 230);
    border-radius: 50%;
    margin: 20px;
    border: none;
}

.snippet-text-box {
    padding: 25px;
    gap: 5px;
}

.snippet-text-title {
    font-size: 22px;
    font-weight: 800;
}

.snippet-text-content {
    color: rgb(184, 184, 184);
}

.snippet-text-information {
    display: none;
}

.snippet-text-information.active {
    display: block;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Minimal Reproducible Example</title>
    <style>
        /* CSS styles will go here */
    </style>
</head>
<body>

<div class="snippet-box-container">
    <div class="snippet-box">
        <div class="snippet-button-box">
            <button class="snippet-button" data-target="#box1">+</button>
        </div>
        <div class="snippet-text-box">
            <div class="snippet-text-title">Lorem Ipsum</div>
            <div class="snippet-text-content">Lorem ipsum dolor sit amet</div>
            <div class="snippet-text-information" id="box1">
                <div class="list-title">Lorem ipsum dolor sit amet:</div>
                <ol>
                    <li>Item 1</li>
                    <li>Item 2</li>
                </ol>
            </div>
        </div>
    </div>

    <div class="snippet-box">
        <div class="snippet-button-box">
            <button class="snippet-button" data-target="#box2">+</button>
        </div>
        <div class="snippet-text-box">
            <div class="snippet-text-title">Lorem Ipsum</div>
            <div class="snippet-text-content">Lorem ipsum dolor sit amet</div>
            <div class="snippet-text-information" id="box2">
                <div class="list-title">Lorem ipsum dolor sit amet:</div>
                <ol>
                    <li>Item 1</li>
                    <li>Item 2</li>
                </ol>
            </div>
        </div>
    </div>
</div>


</body>
</html>


  

I'm working on a layout using Flexbox, where I have multiple containers, each containing collapsible content. When I toggle the expansion/visibility of one collapsible container, all the containers expand in height, which is not the desired behavior. The content of the other boxes doesn't become visible, but their heights increase, matching the one that was toggled.

Expected behavior:
When toggling the visibility of .snippet-text-information by clicking the .snippet-button ''+'' button, only the .snippet-box containing the toggled element should adjust its height accordingly. Other .snippet-box containers should remain at their original height.

Actual behavior:
When I toggle the expansion of one .snippet-text-information element, all .snippet-box containers expand in height, even though only the content of one box is becoming visible. The height of each .snippet-box matches the expanded content of the toggled box.

Code:

    function toggleExtension() {
        const buttons = document.querySelectorAll('.snippet-button');
        buttons.forEach(button => {
            button.addEventListener('click', () => {
                const target = document.querySelector(button.getAttribute('data-target'));
                target.classList.toggle('active');
            });
        });
    }

    window.onload = toggleExtension;
.snippet-box-container {
    display: flex;
    justify-content: center;
    gap: 25px;
    width: 100%;
    padding: 0px 15px;
}

.snippet-box {
    display: flex;
    flex-direction: column;
    min-height: 180px;
    flex-basis: 290px;
    background-color: white;
    box-shadow: 0px 0px 20px rgba(128, 128, 128, 0.1);
    border-radius: 15px;
    box-sizing: border-box;
}

.snippet-button-box {
    display: flex;
    justify-content: flex-end;
}

.snippet-button {
    height: 35px;
    width: 35px;
    background-color: rgb(232, 230, 230);
    border-radius: 50%;
    margin: 20px;
    border: none;
}

.snippet-text-box {
    padding: 25px;
    gap: 5px;
}

.snippet-text-title {
    font-size: 22px;
    font-weight: 800;
}

.snippet-text-content {
    color: rgb(184, 184, 184);
}

.snippet-text-information {
    display: none;
}

.snippet-text-information.active {
    display: block;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Minimal Reproducible Example</title>
    <style>
        /* CSS styles will go here */
    </style>
</head>
<body>

<div class="snippet-box-container">
    <div class="snippet-box">
        <div class="snippet-button-box">
            <button class="snippet-button" data-target="#box1">+</button>
        </div>
        <div class="snippet-text-box">
            <div class="snippet-text-title">Lorem Ipsum</div>
            <div class="snippet-text-content">Lorem ipsum dolor sit amet</div>
            <div class="snippet-text-information" id="box1">
                <div class="list-title">Lorem ipsum dolor sit amet:</div>
                <ol>
                    <li>Item 1</li>
                    <li>Item 2</li>
                </ol>
            </div>
        </div>
    </div>

    <div class="snippet-box">
        <div class="snippet-button-box">
            <button class="snippet-button" data-target="#box2">+</button>
        </div>
        <div class="snippet-text-box">
            <div class="snippet-text-title">Lorem Ipsum</div>
            <div class="snippet-text-content">Lorem ipsum dolor sit amet</div>
            <div class="snippet-text-information" id="box2">
                <div class="list-title">Lorem ipsum dolor sit amet:</div>
                <ol>
                    <li>Item 1</li>
                    <li>Item 2</li>
                </ol>
            </div>
        </div>
    </div>
</div>


</body>
</html>


  

Codepen: https://codepen.io/The-Now/pen/MYWoVQL

I've tried changing display: none to visibility_hidden and tried adding different height properties to the .snippet-text-information, but it didn't work.

I suspect this might be related to how Flexbox handles element heights, but I'm unsure of the exact cause.

Any insights on why this is happening or suggestions on how to fix it with minimal structural changes?

Thanks in advance!

Share edited Mar 8 at 15:02 NotTheDr01ds 21.3k7 gold badges60 silver badges91 bronze badges asked Mar 7 at 18:54 The NowThe Now 231 silver badge7 bronze badges 1
  • Welcome to Stack Overflow! Please do not place answers in the question - You can accept the answer which works best for you. When you have enough reputation, you can return and upvote the other answers as well. If you have your own solution, you can create a self-answer. Thanks! – NotTheDr01ds Commented Mar 8 at 15:04
Add a comment  | 

4 Answers 4

Reset to default 3

This is the standard behavior of flexbox, which happens due to the align-items property (responsible for vertical alignment). By default, it is set to align-items: stretch;, meaning that elements will align to the maximum height of the container. Fixing this is very simple—just change the flex container's value to align-items: flex-start;, and it will resolve the issue.

In your case, you just need to add this value to the .snippet-box-container class.

.snippet-box-container {
    align-items: flex-start;

    display: flex;
    justify-content: center;
    gap: 25px;
    width: 100%;
    padding: 0px 15px;
    box-sizing: border-box;
}

example: https://codepen.io/Neriday/pen/MYWoLYb

Please set the CSS for your snippet-box-container's align-items property to flex-start.

.snippet-box-container{ display: flex; align-items: flex-start; }                                                                          

Please see this link for more help: https://developer.mozilla./en-US/docs/Web/CSS/CSS_flexible_box_layout/Basic_concepts_of_flexbox#align-items

In addition to the answer of SoftwareDevelopper you can also set the property align-self: start; to .snippet-box element. I also suggest to use event delegation.

function toggleExtension() {
    const snippetBox = document.querySelector('.snippet-box-container');
        snippetBox.addEventListener('click', (e) => {
            const target = e.target
            if(target.matches('.snippet-button')){
            const elementToToggleAttribute = target.getAttribute('data-target');
            let elementToToggle = snippetBox.querySelector(elementToToggleAttribute)
            elementToToggle.classList.toggle('active')
            };
        });
}

window.onload = toggleExtension;
.snippet-box-container {
    display: flex;
    justify-content: center;
    gap: 25px;
    width: 100%;
    padding: 0px 15px;
}

.snippet-box {
    display: flex;
    align-self: start; /*add this*/
    flex-direction: column;
    min-height: 180px;
    flex-basis: 290px;
    background-color: white;
    box-shadow: 0px 0px 20px rgba(128, 128, 128, 0.1);
    border-radius: 15px;
    box-sizing: border-box;
}

.snippet-button-box {
    display: flex;
    justify-content: flex-end;
}

.snippet-button {
    height: 35px;
    width: 35px;
    background-color: rgb(232, 230, 230);
    border-radius: 50%;
    margin: 20px;
    border: none;
}

.snippet-text-box {
    padding: 25px;
    gap: 5px;
}

.snippet-text-title {
    font-size: 22px;
    font-weight: 800;
}

.snippet-text-content {
    color: rgb(184, 184, 184);
}

.snippet-text-information {
    display: none;
}

.snippet-text-information.active {
    display: block;
}
<div class="snippet-box-container">
    <div class="snippet-box">
        <div class="snippet-button-box">
            <button class="snippet-button" data-target="#box1">+</button>
        </div>
        <div class="snippet-text-box">
            <div class="snippet-text-title">Lorem Ipsum</div>
            <div class="snippet-text-content">Lorem ipsum dolor sit amet</div>
            <div class="snippet-text-information" id="box1">
                <div class="list-title">Lorem ipsum dolor sit amet:</div>
                <ol>
                    <li>Item 1</li>
                    <li>Item 2</li>
                </ol>
            </div>
        </div>
    </div>

    <div class="snippet-box">
        <div class="snippet-button-box">
            <button class="snippet-button" data-target="#box2">+</button>
        </div>
        <div class="snippet-text-box">
            <div class="snippet-text-title">Lorem Ipsum</div>
            <div class="snippet-text-content">Lorem ipsum dolor sit amet</div>
            <div class="snippet-text-information" id="box2">
                <div class="list-title">Lorem ipsum dolor sit amet:</div>
                <ol>
                    <li>Item 1</li>
                    <li>Item 2</li>
                </ol>
            </div>
        </div>
    </div>
</div>

Thanks to all the contributors! All the suggested answers worked. Adding either align-items: flex-start; to .snippet-box-container or align-self: start; to .snippet-box gave me the result I was looking for!

The explanation from Neriday was very helpful, I'll also explore event delegation, as Mehdi suggested, as well as review Flexbox basics, as SoftwareDveloper recommended. Thanks!

发布评论

评论列表(0)

  1. 暂无评论