skip to Main Content

I’m trying to make a card with a badge inside that extends beyond the card, but all the cards inside the parent should scroll horizontally, however I’m running into a problem where my badge element is hidden behind the overflow, which is a problem for me

selector .c: abstract badge

selector .b: abstract card

selector .a: abstract list cards

CSS

        .a {
            width: 150px;
            height: 200px;
            border: solid 1px silver;
            margin: 200px;
            
            /* important */
            display: flex;
            overflow-x: scroll;
        }
        
        .b {
          width: 100px;
          height: 100px;
          border: 1px solid blue;
          
          /* important */
          position: relative;
        }
        
        .c {
            width: 100px;
            height: 100px;
            border: solid 1px red;
            margin-top:-50px;
            
            /* important */
            position: absolute;
        }

HTML

    <div class="a">
        <div class="b">
          <div class="c"></div>
        </div>
        <div class="b">
          <div class="c"></div>
        </div>
    </div>

I solved this problem when I made padding for a list with overflow, but this created another problem in the layout, so I had to abandon this solution

example (its not solution for me)

        .a {
            width: 150px;
            height: 200px;
            border: solid 1px silver;
            margin: 200px;
            
            /* important */
            display: flex;
            overflow-x: scroll;
            
            padding-top: 50px;
        }
.a {
  width: 150px;
  height: 200px;
  border: solid 1px silver;
  margin: 200px;
  /* important */
  display: flex;
  overflow-x: scroll;
}

.b {
  width: 100px;
  height: 100px;
  border: 1px solid blue;
  /* important */
  position: relative;
}

.c {
  width: 100px;
  height: 100px;
  border: solid 1px red;
  margin-top: -50px;
  /* important */
  position: absolute;
}
<div class="a">
  <div class="b">
    card
    <div class="c">badge</div>
  </div>
  <div class="b">
    card
    <div class="c">badge</div>
  </div>
</div>

3

Answers


  1. Chosen as BEST ANSWER

    I managed to come up with a solution, it doesn't look pretty, but it suits my needs. Apparently overflow: scroll is not at all friendly with positioning and does not allow elements beyond the height of the root element to be visually displayed (in this example it is a card), but if you try to position elements using negative values, then everything will work, because the element is not has absolute position settings and has its own height to which the scroll container is forced to adjust

    <style>
    .container {
        display: flex;
        width: 400px;
        border: 1px solid red;
        padding: 5px;
        overflow-x: scroll;
    }
    
    .card {
        width: 250px;
        height: 200px;
        border: 1px solid blue;
    }
    
    .badge {
        margin: auto;
        border: 1px solid green;
        width: 100px;
        height: 50px;
        margin-bottom: -25px;
    }
    </style>
    <div class="container">
        <div class="card-container">
            <div class="badge">
                badge
            </div>
            <div class="card">
                card
            </div>
        </div>
        <div class="card-container">
            <div class="badge">
                badge
            </div>
            <div class="card">
                card
            </div>
        </div>
    </div>


  2. you can use the z-index property to control the stacking order of elements. Set a higher z-index value for the badge (.c class) so that it appears above the overflowed content. Also, make sure that the parent container (.a class) has a position: relative property, as z-index only works on positioned elements.

    .a {
        width: 150px;
        height: 200px;
        border: solid 1px silver;
        margin: 200px;
    
        /* important */
        display: flex;
        overflow-x: scroll;
        position: relative; /* Make sure to add this line */
    }
    
    .b {
        width: 100px;
        height: 100px;
        border: 1px solid blue;
    
        /* important */
        position: relative;
    }
    
    .c {
        width: 100px;
        height: 100px;
        border: solid 1px red;
        margin-top: -50px;
    
        /* important */
        position: absolute;
        z-index: 1; /* Add this line to control the stacking order */
    }
    
    Login or Signup to reply.
  3. Maybe this can get you a starting point. I did not "directly" answer the question but more did what I thought you were after.

    I wrapped the container in a div and gave it a light green border just to "super center" the block in the window. I also added a 100vh to the body and super-centered my new contain on that – so no magic large margin needed, just let if flow in the window at the center.

    I created some grids for your elements and put the content using your sizing; I converted to em so based on a common browser default I set to 16px font size thus 100px converts to 100/16 or 6.25em I then gave the card some rows/columns based on that – create more rows and columns as you see fit to get the badge and card label where you want them; then expand the number of rows/columns and place them within those to capture your desired layout. Using this type of technique I find I very seldom use any "position" like absolute etc. these days.

    * {
      font-size: 16px;
      box-sizing: border-box;
      margin: 0;
      padding: 0;
    }
    
    body {
      display: grid;
      place-items: center;
      height: 100vh;
    }
    
    .base-container {
      display: grid;
      place-items: center;
      border: solid #00ff0040 2px;
      padding: 0.25em;
    }
    
    .scroll-container {
      width: 10em;
      height: 12.5em;
      border: solid 1px silver;
      display: flex;
      column-gap: 0.5em;
      overflow-x: scroll;
    }
    
    .card-container {
      display: grid;
      grid-template-rows: 1fr;
      column-gap: 1em;
      grid-template-columns: 9.375em;
      grid-template-areas: "card";
    }
    
    .b-card {
      grid-area: card;
      display: grid;
      grid-template-rows: 3.125em 1fr;
      grid-template-columns: 3.125em 6.25em;
      grid-template-areas: ". cardlabel" "badge cardlabel";
      border: 1px solid blue;
      display: grid;
      grid-template-rows:
    }
    
    .card-badge {
      grid-area: badge;
      border: solid 1px red;
    }
    
    .card-label {
      grid-area: cardlabel;
      border: solid 1px #00ffff;
    }
    <div class="base-container">
      <div class="scroll-container">
        <div class="card-container">
          <div class="b-card">
            <div class="card-label">card</div>
            <div class="card-badge">badge</div>
          </div>
        </div>
        <div class="card-container">
          <div class="b-card">
            <div class="card-label">card</div>
            <div class="card-badge">badge</div>
          </div>
        </div>
        <div class="card-container">
          <div class="b-card">
            <div class="card-label">card</div>
            <div class="card-badge">badge</div>
          </div>
        </div>
        <div class="card-container">
          <div class="b-card">
            <div class="card-label">card</div>
            <div class="card-badge">badge</div>
          </div>
        </div>
        <div class="card-container">
          <div class="b-card">
            <div class="card-label">card</div>
            <div class="card-badge">badge</div>
          </div>
        </div>
      </div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search