Tips for avoiding a large <ul> element from spilling over the body in a flexbox design

I struggled to articulate the problem I am facing, and I apologize if it's still unclear

So, in my app, I have 3 cards, and the 2 side ones contain lists (<ul>) that can become quite lengthy. I want the scrollbar to appear on the <ul> itself, not on the "main window".

This is the desired appearance:

https://i.stack.imgur.com/Y7UAm.png

However, this is what currently happens:

https://i.stack.imgur.com/AybkA.png

To achieve the first screenshot, I set max-height: 80vh on my lists, but this is not an ideal solution as it only works for a specific screen size.

Here's the link to the codepen, simply click on "Add more items" a few times to see the issue

Below is the CSS for the main section and the basic HTML structure, in case you prefer not to check the codepen

<div class="room-wrapper">
  <div><button class="btn btn-primary add-more-btn">Add more items</button></div>
  <div class="room-content">

    <div class="left-card app-card">
      <div class="left-card-wrapper">
        <div>
          <h3>Left Card</h3>
          <hr>
        </div>
        <ul class="my-list"></ul>
      </div>
    </div>

    <div class="main-card app-card"></div>

    <div class="right-card app-card">
      <div class="players-wrapper">
        <div>
          <h3>Right Card</h3>
          <hr>
        </div>
        <ul class="my-list"></ul>
      </div>
    </div>

  </div>
</div>
.room-wrapper {
  display: flex;
  flex-flow: column;
  height: 100%;
  padding: 10px;
}

.room-content {
  flex: 1 1 auto;
  text-align: center;
  
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
}

.my-list {
  overflow-y: auto;
  
  /* This would "solve" it, but only for a very
  specific window size, this is what I used for
  the first screenshot
  
  max-height: 80vh;
  */
}

Answer №1

After implementing some small adjustments and utilizing flex properties, I managed to get the solution to work flawlessly.

To achieve a perfect layout, simply insert the additional CSS provided below:

.my-list {
  flex: 1 1 1px;
}

.players-wrapper,
.left-card-wrapper {
  height: 100%;
  display: flex;
  flex-direction: column;
}

$(".add-more-btn").click(() => {
  $(".list-group").append("<li class=\"list-group-item\">Item</li>");
});
body,
html {
  height: 100%;
}

body {
  background-color: #dadada;
}

/* Rest of the CSS code continues... */
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<div class="room-wrapper">
  <!-- The rest of the HTML markup continuation -->
</div>

Answer №2

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    background-color: #dadada;
}

.room-wrapper {
    display: flex;
    flex-flow: column;
    height: 100%;
    padding: 10px;
}

.room-content {
    flex: 1 1 auto;
    text-align: center;
    display: flex;
    justify-content: center;
    flex-wrap: wrap;
}

.app-card {
    height: 85vh;
    border-radius: 10px;
    margin: 10px 10px;
    padding: 10px;
    background-color: white;
    flex-basis: 0;
    flex-grow: 1;
    flex-shrink: 1;
}

.main-card {
    flex-grow: 2!important;
}

.form-wrapper {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    height: 100%;
}

.my-list {
    display: block;
    height: 90%;
    overflow-y: auto;
}

.add-more-btn {
    margin: 10px;
}
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>document</title>
    <link rel="stylesheet" href="style.css" />
</head>

<body>
    <div class="room-wrapper">
        <div><button class="btn btn-primary add-more-btn">Click here to Add more items!</button></div>
        <div class="room-content">

            <div class="left-card app-card">
                <div>
                    <h3>Left Card</h3>
                    <hr>
                </div>
                <ul class="my-left-list">
                   <!-- Repeating list items go here -->
                </ul>
            </div>

            <div class="main-card app-card"></div>

            <div class="right-card app-card">
                <div>
                    <h3>Right Card</h3>
                    <hr>
                </div>
                <ul class="my-right-list">
                  <!-- Repeating list items go here -->
                </ul>
            </div>

        </div>
    </div>
    <script src="script.js"></script>
</body>

</html>

Answer №3

Take a look at this to see if it meets your needs! You can view the code here : On codepen

body, html {
  height: 100%;
}

body {
  background-color: #dadada !important;
}


.room-wrapper {
  display: flex;
  flex-flow: column;
  height: 100%;
  padding: 10px;
}

.room-content {
  flex: 1 1 auto;
  text-align: center;
  height: calc(100% - 78px);
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
}

.app-card {
  border-radius: 10px;
  margin: 10px 10px;
  padding: 10px;
  background-color: white;
  flex-basis: 0;
  flex-grow: 1;
  flex-shrink: 1;
  height:98%;
}

.main-card {
  flex-grow: 2!important;

}
.form-main{
    height:calc(100% - 78px);
  overflow:auto;
}
.form-wrapper {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  height: 100%;
}

.my-list {
    overflow-y: auto;
    height: calc(100% - 78px);
}

.add-more-btn {
  margin: 10px;
}

.right-card>div,.left-card>div{
  height:100%;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.6.0/css/bootstrap.min.css" rel="stylesheet"/>
<body>
  <div class="room-wrapper">
  <div><button class="btn btn-primary add-more-btn">Add more items</button> <button type="submit" class="btn btn-primary">Submit</button></div>
 
  <div class="room-content">
    <div class="left-card app-card">
      <div class="left-card-wrapper ">
        <div>
          <h3>Left Card</h3>
          <hr>
        </div>
        <ul class="list-group text-left my-list">
          <li class="list-group-item">Item</li>
          <li class="list-group-item">Item</li>  
          <li class="list-group-item">Item</li>  
          <li class="list-group-item">Item</li>  
          <li class="list-group-item">Item</li>  
          <li class="list-group-item">Item</li>  
          <li class="list-group-item">Item</li>  
          <li class="list-group-item">Item</li>  
          <li class="list-group-item">Item</li>  
          <li class="list-group-item">Item</li>  
          <li class="list-group-item">Item</li>  
          <li class="list-group-item">Item</li>  
        </ul>
      </div>
    </div>
    <div class="main-card app-card">
      <div class="form-wrapper">
        <div class="form-header">
          <h3>Form</h3>
          <hr>
        </div>
        <div class="form-main">
          <form>
            <div class="form-group">
              <label for="exampleFormControlInput1">Email address</label>
              <input type="email" class="form-control" id="exampleFormControlInput1" placeholder="<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="f39d929e96b3968b929e839f96dd909c9e">[email protected]</a>">
            </div>
            <div class="form-group">
              <label for="exampleFormControlSelect1">Example select</label>
              <select class="form-control" id="exampleFormControlSelect1">
                <option>1</option>
                <option>2</option>
                <option>3</option>
                <option>4</option>
                <option>5</option>
              </select>
            </div>
            <div class="form-group">
              <label for="exampleFormControlSelect2">Example multiple select</label>
              <select multiple class="form-control" id="exampleFormControlSelect2">
                <option>1</option>
                <option>2</option>
                <option>3</option>
                <option>4</option>
                <option>5</option>
              </select>
            </div>
            <div class="form-group">
              <label for="exampleFormControlTextarea1">Example textarea</label>
              <textarea class="form-control" id="exampleFormControlTextarea1" rows="3"></textarea>
            </div>
          </form>
        </div>
        
      </div>
    </div>
    <div class="right-card app-card">
      <div class="players-wrapper">
        <div>
          <h3>Right Card</h3>
          <hr>
        </div>
        <ul class="list-group text-left my-list">
          <li class="list-group-item">Item</li>
          <li class="list-group-item">Item</li>  
          <li class="list-group-item">Item</li>  
          <li class="list-group-item">Item</li>  
          <li class="list-group-item">Item</li>  
          <li class="list-group-item">Item</li>  
          <li class="list-group-item">Item</li>  
          <li class="list-group-item">Item</li>  
          <li class="list-group-item">Item</li>  
          <li class="list-group-item">Item</li>  
          <li class="list-group-item">Item</li>  
          <li class="list-group-item">Item</li>  
        </ul>
      </div>
    </div>
  </div>
</div>
</body>

Answer №4

.room-content {
  display: flex;
  box-shadow: inset 0px 0px 7px #ccc;
  padding: 1rem 2rem;
  margin-top: 2rem;
  background: #f6f6f6;
}
.room-content > div {
  flex: 1;
  border: 1px solid #e4e4e4;
  padding: 1rem;
  background: white;
  margin-right: 1rem;
  border-radius: 10px;
}
.room-content > div:last-child {
  margin-right: 0rem;
}
ul {
  padding: 0;
  overflow: scroll;
  height: 72vh;
}
.list-group-item {
  list-style-type: none;
  padding-block: 10px;
  border-bottom: 1px solid #eae9e9;
}
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Three List</title>
  </head>

  <body>
    <div class="room-wrapper">
      <div>
        <button class="btn btn-primary add-more-btn">Add more items</button>
      </div>
      <div class="room-content">
        <div class="left-card app-card">
          <div>
            <h3>Left Card</h3>
            <hr />
          </div>
          <ul class="my-list">
            <li class="list-group-item">Item</li>
            <li class="list-group-item">Item</li>
(remaining list items have been omitted)

          </ul>
        </div>

        <div class="main-card app-card"></div>

        <div class="right-card app-card">
          <div>
            <h3>Right Card</h3>
            <hr />
          </div>
          <ul class="my-list">
            <li class="list-group-item">Item</li>
            <li class="list-group-item">Item</li>
(remaining list items have been omitted)

          </ul>
        </div>
      </div>
    </div>
    <script src="script.js"></script>
  </body>
</html>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for incorporating images as radio buttons

Can anyone assist me in setting up a straightforward enabled/disabled radio button grouping on my form? My idea is to utilize an image of a check mark for the enabled option and an X for disabled. I would like the unselected element to appear grayed out ...

Creating a design that resembles boxes for the div elements while ensuring the grid layout remains undisturbed

Hey there! I'm new to using Bootstrap and I'm trying to create boxes that look like the ones on the right side of this page: Unfortunately, I haven't had much luck so far. I tried using padding, but it messed up my grid system. I assigned a ...

Toggle the class and execute the order within a jQuery script

When the mouse moves in, the jQuery trigger enters the status. $(".test").bind("mouseenter mouseout", function(event) { $(this).toggleClass("entered"); alert("mouse position (" + event.pageX + "," + event.pageY + ")"); }); .entered { ...

Choosing radio buttons within rows that contain two radio buttons using ngFor

This section showcases HTML code to demonstrate how I am iterating over an array of objects. <div class="row" *ngFor="let item of modules; let i = index;"> <div class="col-md-1 align-center">{{i+1}}</div> <div class="col-md- ...

Positioning a single column of iframes in the center

I have 6 graphs that I need to arrange in a grid with 2 rows and 3 columns. Each row should have one left-aligned graph, one center-aligned graph, and one right-aligned graph. However, the center-aligned graphs are not displaying correctly. Can someone hel ...

Manipulating AngularJS with Sass variables

Currently, I am developing a theme changer using AngularJS and I'm facing difficulty in figuring out how to swap one SASS file with another (both containing variables) when the user changes their theme. I understand that once SASS is compiled to CSS, ...

steps for executing a Google script

In my program, the structure is as follows: // JavaScript function using Google Script 1. function F1() { ...... return (v1); } // HTML code for Google 1. <script> 2. function F2() { 3. alert ( 1 ); 4. function F2(); 5. alert ( 2 ); 6 ...

Is there a way to enhance the height of Bootstrap combobox items? Can this be achieved?

Is it possible to improve the height of Bootstrap combobox item? How can I achieve that? 1 2 3 4 ...

Utilizing the '<' or '>' operator in combination with an if statement within a Repeater component

Is it possible to use an if statement in a repeater like this? <%#Eval("FN").ToString().Count > 0 ? "SB" : "" %> When I try to implement this, I receive an error 73 indicating that the > operator cannot be used. How can I adjust it so that i ...

Move your cursor over an image within a div container

After not finding any helpful answers on this topic, I've decided to ask for help again. My issue involves having an image inside a div. <div id ="gratterlendis"> <a href ="?page_id=8"><img src="img/gratterlendis.png" align="right" wid ...

Conceal the URL and any parameters upon successful completion of AJAX request

In my ajax js code, the solonreport.jsp file returns a URL link that connects to a local report server and generates an Excel report. However, when using this link with the window.open(json.url) function, the link and parameters are visible to the user. ...

Is it possible to validate link clicks and integrate PHP within JavaScript functions?

Before anyone mentions security concerns, please refrain. Imagine I have an index.php. This page contains several links to 'home.php', each with different data stored in the href attributes. For example: Link 1: 'home.php?data=1&count ...

Is it acceptable to include a checkbox and a hidden input within a label element?

When creating a list of possible products for users to buy, I use the ul tag combined with li. Each product element includes a checkbox that allows users to select the product or not. For products with related information, I want to store this data in a h ...

Retrieving the chosen value when there is a change in the select tag

Building a shop and almost done, but struggling with allowing customers to change product quantities in the cart and update prices dynamically. I've created a select-tag with 10 options for choosing quantities. I'd like users to be able to click ...

What should be done if an image is not wide enough to stretch it to match the width of the window?

When the image is not full screen, it looks fine but when it's viewed in full screen, there's a white area on the right side which is likely due to the image not being large enough. Is there a way to automatically stretch the image so that its wi ...

audio enhancement in a web-based game

I'm having trouble getting a sound effect to play consistently in my game whenever there is a hit. Sometimes the sound plays, other times it does not! Here is the code I am using: <script> var hitSound = new Audio(); function playEffectSound ...

How can I prevent a span in CSS from stretching its parent element?

Utilizing the twitter bootstrap thumbnails successfully, we have implemented a description feature inspired by the bootstrap documentation. The distinction lies in our decision not to specify a size (e.g., .span4) for our thumbnails; instead, the content d ...

Angular CSS: ng-style applied to only one side, the other remains unaffected

I am working on an Angular application that requires a split screen with two halves, each displaying the same array values. The width and height values are set using a service and accessed by a controller. The style is applied using ng-style in the DOM. Ho ...

Looking to implement a delay in the model popup using Pure JavaScript

Looking for a method to implement a delay in the popup... I've tried a few solutions without success. What's the secret to adding a delay to the modal below? Any help is greatly appreciated. var modal = document.querySelector(".modal"); var t ...

Card columns with dropdown extending into adjacent column

Encountering a strange problem with the card-columns layout in Bootstrap when using dropdown menus within the cards. The issue arises when the dropdown-menu divs of the lower cards bleed into the next column, despite appearing in the correct position. Thi ...