skip to Main Content

I am trying to create an indicator of horizontal scrollable content that only shows when an overflow occurs.

The red square, which will be the indicator that there is overflowed scrollable content, but I cannot find a way to get it to stay fixed to the right scrollable edge.

.rpt {
  display: inline-grid;
  position: relative;
  overflow-x: auto;
  width: 100%;
}

.rpt::after {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  width: 30px;
  height: 30px;
  background: #b00;
  pointer-events: none;
  z-index: 1;
}

.rpt .rpt-row {
  flex-wrap: nowrap;
  display: flex;
  flex: 1 1 0%;
  height: 50px;
}

.flx-item {
  width: 100px;
}
<div class="rpt">
  <div class="rpt-row">
    <div class="flx-item">
      <span>Lipsum</span>
    </div>
    <div class="flx-item">
      <span></span>
    </div>
    <div class="flx-item">
      <span>12345</span>
    </div>
    <div class="flx-item">
      <span>25</span>
    </div>
    <div class="flx-item">
      <span>1</span>
    </div>
    <div class="flx-item">
      <span>0</span>
    </div>
    <div class="flx-item">
      <span>0</span>
    </div>
    <div class="flx-item">
      <span>0</span>
    </div>
    <div class="flx-item">
      <span>0</span>
    </div>
  </div>
</div>

I would prefer not to alter HTML if possible, but am open to using JavaScript if CSS cannot achieve this alone.

2

Answers


  1. What you want is position: sticky, not absolute, but the parent has display:grid, so you need to add grid-row-start: 1 to both the indicator and the first row make them overlap instead of creating another row.

    .rpt {
      display: inline-grid;
      position: relative;
      overflow-x: auto;
      width: 100%;
    }
    
    .rpt::after {
      content: "";
      display: block;
      position: sticky;
      top: 0;
      right: 0;
      width: 30px;
      height: 30px;
      background: #b00;
      z-index: 1;
      pointer-events: none;
      grid-row-start: 1;
    }
    
    .rpt .rpt-row {
      flex-wrap: nowrap;
      display: flex;
      flex: 1 1 0%;
      height: 50px;
    }
    
    .rpt .rpt-row:first-child {
      grid-row-start: 1;
    }
    
    .flx-item {
      width: 100px;
    }
    <div class="rpt">
      <div class="rpt-row">
        <div class="flx-item">
          <span>Lipsum</span>
        </div>
        <div class="flx-item">
          <span></span>
        </div>
        <div class="flx-item">
          <span>12345</span>
        </div>
        <div class="flx-item">
          <span>25</span>
        </div>
        <div class="flx-item">
          <span>1</span>
        </div>
        <div class="flx-item">
          <span>0</span>
        </div>
        <div class="flx-item">
          <span>0</span>
        </div>
        <div class="flx-item">
          <span>0</span>
        </div>
        <div class="flx-item">
          <span>0</span>
        </div>
      </div>
    </div>
    Login or Signup to reply.
  2. All you have to do is to put position:fixed; for .rpt::after

    .rpt {
      display: inline-grid;
      position: relative;
      overflow-x: auto;
      width: 100%;
    }
    
    .rpt::after {
      content: "";
      position: fixed;
      top: 0;
      right: 0;
      width: 30px;
      height: 30px;
      background: #b00;
      pointer-events: none;
      z-index: 1;
    }
    
    .rpt .rpt-row {
      flex-wrap: nowrap;
      display: flex;
      flex: 1 1 0%;
      height: 50px;
    }
    
    .flx-item {
      width: 100px;
    }
    <div class="rpt">
      <div class="rpt-row">
        <div class="flx-item">
          <span>Lipsum</span>
        </div>
        <div class="flx-item">
          <span></span>
        </div>
        <div class="flx-item">
          <span>12345</span>
        </div>
        <div class="flx-item">
          <span>25</span>
        </div>
        <div class="flx-item">
          <span>1</span>
        </div>
        <div class="flx-item">
          <span>0</span>
        </div>
        <div class="flx-item">
          <span>0</span>
        </div>
        <div class="flx-item">
          <span>0</span>
        </div>
        <div class="flx-item">
          <span>0</span>
        </div>
      </div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search