skip to Main Content

I’d like to have a card with a fixed header, and scrollable contents.

diagram of card size/scroll

I’ve figured out how to do something similar by setting a fixed height to the card, and using overflow scrolling.

<div class="card">

  <div class="sticky-header">
      <!-- title -->
  </div>

  <div class="overflow-contents">
      <!-- contents -->
  </div>

</div>
.card {
  height: calc(100vh - 32px);
  display: flex;
  flex-direction: column;
  overflow: scroll;
}

.sticky-header {
  display: sticky;
  top: 0px;
}

.overflow-contents {
  display: flex;
  flex-wrap: wrap;
}

https://codepen.io/david-schultz/pen/mdQobQV

However, what I’m actually trying to achieve is to have something like flexible card height. I.e. the card’s height depends on the amount of overflowing content. (I’m not sure if this is actually how to solve this problem, but it’s the mental model I have right now.)

2

Answers


  1. Just remove your height rules?

    .fixed {
      display: fixed;
    }
    
    .sticky {
      position: sticky;
    }
    
    .wrapper {
      width: 100%;
    /*  height: calc(100vh - 32px); */
      display: flex;
      flex-direction: row;
      margin: 16px;
      gap: 64px;
    }
    
    .card {
    /*  height: calc(100vh - 32px); */
      width: 400px;
      display: flex;
      flex-direction: column;
    /*  overflow: scroll; */
    }
    
    .card > * {
      padding-left: 16px;
    }
    
    .tab-contents {
      display: flex;
      flex-wrap: wrap;
    }
    
    .header1 {
      top: 0px;
      background: #F1F1F1;
    }
    
    .header2 {
      top: 64px;
      background: #F4F4F4;
    }
    
    .card {
      background: #FAFAFA;
      border-radius: 0.5rem;
      box-shadow: 0px 0px 0px 1px rgba(59, 83, 105, 0.08), 0px 0px 4px 1px rgba(0, 0, 0, 0.05);
    }
    
    .block {
      height: 50px;
      width: 50px;
      margin: 16px;
      background: #000000;
    }
    <div class="wrapper">
      <h1 class="fixed">👋 Hello World!</h1>
      <div class="card">
        <div class="sticky header1"><h2>header</h2></div>
    
        <div>
          <h4>a component library for charts</h4>
          <p>An exploration into the UX of figma libraries — from a designer, developer, and architect’s perspective.</p>
        </div>
    
        <div class="sticky header2"><h6>tabs</h6></div>
    
        <div class="tab-contents">
          <div class="block">hi</div>
          <div class="block"></div>
          <div class="block"></div>
          <div class="block"></div>
          <div class="block"></div>
          <div class="block"></div>
          <div class="block"></div>
          <div class="block"></div>
          <div class="block"></div>
          <div class="block"></div>
          <div class="block"></div>
          <div class="block"></div>
          <div class="block"></div>
          <div class="block"></div>
          <div class="block"></div>
          <div class="block"></div>
          <div class="block"></div>
        </div>
    
      </div>
    </div>
    Login or Signup to reply.
  2. If you want a card with a fixed header and a scrollable content area, and you want the card’s height to be flexible depending on the amount of overflowing content, you can achieve this using CSS Flexbox and setting the overflow property appropriately. Here’s how you can modify your existing code to achieve the desired effect:

    .card {
      display: flex;
      flex-direction: column;
      border: 1px solid #ccc;
      overflow: hidden;
    }
    
    .sticky-header {
      position: sticky;
      top: 0;
      background-color: #f2f2f2;
      /* Add any other styles you want for the sticky header */
    }
    
    .overflow-contents {
      flex: 1; /* This allows the contents to expand and take remaining space */
      overflow-y: auto; /* Allows the content to scroll when it overflows */
      padding: 10px;
      background-color: #fff;
      /* Add any other styles you want for the scrollable content area */
    }
    <div class="card">
      <div class="sticky-header">
        <!-- title -->
      </div>
      <div class="overflow-contents">
        <!-- contents -->
      </div>
    </div>

    With the updated CSS, the .card container is now a flex container, and the .overflow-contents div is given flex: 1, which allows it to take up the remaining vertical space. When the content inside .overflow-contents exceeds the available space, it will automatically start scrolling.

    The overflow: hidden is still applied to the .card, but the .overflow-contents div will expand to accommodate the content, and any overflowing content will be scrollable within this div.

    With this approach, the height of the card will be flexible and adapt to the content inside the .overflow-contents div, while keeping the header (.sticky-header) fixed at the top of the card.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search