Home > Software engineering >  Move Dropdown Content to the left if it overflows
Move Dropdown Content to the left if it overflows

Time:11-13

I have a Navigation bar at the top of the browser window with different dropdown menus. A few are on the left, a few on the right.

The Problem:

If the Content of the Dropdown is large, it automatically extends the div where it's contained within. This only becomes a Problem as soon as it goes off screen.

The Code:

:root {
    /* Theme */
    --theme_color: #fff;
    --theme_color_select: #BBB;

    --theme_text: #000;
    --theme_text_select: #444;

    --theme_shadow: #0004;
    --theme_shadow_select: #4444;
}

/* Taskbar */
#taskbar {
    position: sticky;
    display: flex;
    justify-content: space-between;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    height: 3em;
    width: 100%;
    background-color: var(--theme_color);
    box-shadow: 2px 2px 2px 2px var(--theme_shadow);
    z-index: 1;
}

#taskbar .dropdown-name {
    line-height: 3em;
    min-width: 4em;
    text-align: center;
    vertical-align: middle;
}

#taskbar .button {
    padding: 0;
    border: 0;
    /* width: 4em; */
}
#taskbar .dropdown-content {
    background-color: var(--theme_color);
    box-shadow: 0px 0px 4px 4px var(--theme_shadow);
    border: 4px solid #0000;
    border-radius: 4px;
}

/* Dropdowns */
.dropdown {
    position: relative;
    display: inline-block;
}

.dropdown-content {
    display: none;
    position: absolute;
    z-index: 2;
    flex-direction: column;
    max-width: 50vw;
}

.dropdown-name {
    cursor: default;
    -webkit-user-select: none;
    user-select: none;
}

.dropdown:hover .dropdown-content {
    display: flex;
}
.dropdown:hover .dropdown-name {
    background-color: var(--theme_color_select);
}
<header id="taskbar">
    <section id="taskbar_left">
        <div >
            <div >UwU</div>
            <div >
                <button>Create Column</button>
                <button>Button 2 uwuuwuuwuuwuuwuwuwuwuwuuwuwuwuwuuwuwuwuuwuwuuwuuwu</button>
                <button>Button 3 h</button>
            </div>
        </div><div >
            <div >UwU</div>
            <div >
                <button>Create Column</button>
                <button>Button 2 uwuuwu</button>
                <button>Button 3 h</button>
            </div>
        </div>
    </section>
    <section id="taskbar_right">
        <div >
            <div >UwUwUwUwUwUwU</div>
            <div >
                <button>Create Column</button>
                <button>Button 2 uwuuwuuwuuwuuwuwuwuwuwuuwuwuwuwuuwuwuwuuwuwuuwuuwu</button>
                <button>Button 3 h</button>
            </div>
        </div>
    </section>
</header>

My Attempts:

  • I added to the CSS #taskbar_right .dropdown-content {transform: translate(calc(4em - 100%), 0);} to move every dropdown content contained in the right Taskbar to be moved. However, if the Text of the class "dropdown-name" is bigger than 4em it isn't perfectly aligned to the right side anymore.
  • I also tried using the left, right, top and bottom CSS, but that doesn't work, because the dropdown-content is absolutely positioned, so it just gets completely messed up.

What I need:

A "Simple" way of shifting the content the exact amount to the left it goes off screen. It would be best if the solution only includes CSS, or if it's impossible, then JavaScript. No jQuery, the Rest of my code works without it.

PS: The CSS is just a portion of all the 340 Lines of CSS, here it only contains the most Relevant.

PPS: The text inside the button elements is just for testing purposes.

PPPS: Where do I add Code Snippets? There's no button for it. There's only "Link, Blockquote, Code Block, Image, Table". There's no 6th button... am I missing something?

CodePudding user response:

Position the right taskbar's dropdown content to the right.

#taskbar_right .dropdown-content {
  right: 0;
}

:root {
    /* Theme */
    --theme_color: #fff;
    --theme_color_select: #BBB;

    --theme_text: #000;
    --theme_text_select: #444;

    --theme_shadow: #0004;
    --theme_shadow_select: #4444;
}

/* Taskbar */
#taskbar {
    position: sticky;
    display: flex;
    justify-content: space-between;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    height: 3em;
    width: 100%;
    background-color: var(--theme_color);
    box-shadow: 2px 2px 2px 2px var(--theme_shadow);
    z-index: 1;
}

#taskbar .dropdown-name {
    line-height: 3em;
    min-width: 4em;
    text-align: center;
    vertical-align: middle;
}

#taskbar .button {
    padding: 0;
    border: 0;
    /* width: 4em; */
}

#taskbar .dropdown-content {
    background-color: var(--theme_color);
    box-shadow: 0px 0px 4px 4px var(--theme_shadow);
    border: 4px solid #0000;
    border-radius: 4px;
}

#taskbar_right .dropdown-content {
    right: 0;
}

/* Dropdowns */
.dropdown {
    position: relative;
    display: inline-block;
}

.dropdown-content {
    display: none;
    position: absolute;
    z-index: 2;
    flex-direction: column;
    max-width: 50vw;
}

.dropdown-name {
    cursor: default;
    -webkit-user-select: none;
    user-select: none;
}

.dropdown:hover .dropdown-content {
    display: flex;
}
.dropdown:hover .dropdown-name {
    background-color: var(--theme_color_select);
}
<header id="taskbar">
    <section id="taskbar_left">
        <div >
            <div >UwU</div>
            <div >
                <button>Create Column</button>
                <button>Button 2 uwuuwuuwuuwuuwuwuwuwuwuuwuwuwuwuuwuwuwuuwuwuuwuuwu</button>
                <button>Button 3 h</button>
            </div>
        </div><div >
            <div >UwU</div>
            <div >
                <button>Create Column</button>
                <button>Button 2 uwuuwu</button>
                <button>Button 3 h</button>
            </div>
        </div>
    </section>
    <section id="taskbar_right">
        <div >
            <div >UwUwUwUwUwUwU</div>
            <div >
                <button>Create Column</button>
                <button>Button 2 uwuuwuuwuuwuuwuwuwuwuwuuwuwuwuwuuwuwuwuuwuwuuwuuwu</button>
                <button>Button 3 h</button>
            </div>
        </div>
    </section>
</header>

CodePudding user response:

You can right dropdown fired by the last menu. That would work in "almost" all situation.

Now if dropdown fired by not the last one but the one just before is large, it can overflow too.

If you want to have it bullet proof, you'll need some calculation:

  • get bounding rect of the menu which fired dropdown
  • get bounding rect of the dropdown. Assuming it's not display none, otherwise no values. In this case put opacity 0, and display inline or inline block just at the moment of the calculation
  • if menu left dropdown width is more than viewport width, you position the dropdown left at menu right - dropdown width.

You can check here: https://github.com/pierfarrugia/drop_down_click

Not exactly the same. Dropdown there is fired by click, and taking care also of top (it's for scrolling header). But the left-right calculation is same.

  • Related