Set child width to parent inner width (scroll width / overflow scroll)

Viewed 222

I have two rows with columns. The bottom bar later contains blocks which matches the ruler numbers. So both rows should have the same length if one of them exceeds the parent width (overflow scroll).

But currently the bottom bar is always 100% of the initial parent width. But I expected the following: The first row width increases the inner width of the parent. The bottom row should fill that dynamic width. Is there a way to keep this element separated as it is, but have the same width?

No JavaScript.

There are similar questions and solution on the web / stackoverflow. But nothing works in my case. It looks trivial, but I have no idea. I feel like a noob. ^^ The DOM structure should be retained.

Background: I want to implement a ruler with some annotations at the bottom. Blocks with start and stop. I could use a canvas to achieve that. But I would prefer HTML. I would be grateful for any help.

Stackblitz Demo

demo

Screenshot

body {
  width: 100%;
  height: 100%;
  margin: 0;
}

.container {
  width: 100%;
  overflow-x: auto;
}

.wrapper {
  display: flex;
}

.text {
  min-width: 30px;
  flex: 1;
  text-align: center;
}

.text:nth-child(even) {
  background-color: #ddd;
}

.bar {
  background-color: green;
  height: 30px;
  flex: 1;
}
<div class="container">
  <div class="wrapper">
    <div class="text">1</div>
    <div class="text">2</div>
    <div class="text">3</div>
    <div class="text">4</div>
    <div class="text">5</div>
    <div class="text">6</div>
    <div class="text">7</div>
    <div class="text">8</div>
    <div class="text">9</div>
    <div class="text">10</div>
    <div class="text">11</div>
    <div class="text">12</div>
    <div class="text">13</div>
    <div class="text">14</div>
    <div class="text">15</div>
    <div class="text">16</div>
    <div class="text">17</div>
    <div class="text">18</div>
    <div class="text">19</div>
    <div class="text">20</div>
    <div class="text">21</div>
    <div class="text">22</div>
    <div class="text">23</div>
    <div class="text">24</div>
    <div class="text">25</div>
    <div class="text">26</div>
    <div class="text">27</div>
    <div class="text">28</div>
    <div class="text">29</div>
    <div class="text">30</div>
  </div>
  <div class="bar"></div>
</div>

2 Answers

I made it working with one more additional wrapper div for bar and elements.

.scroll {
  width: 500px;
  overflow: auto;
}

.scroll__wrapper {
  width: fit-content;
}

.scroll__elements {
  display: flex;
  background: pink;
  width: fit-content;
}

.text {
  flex-shrink: 0;
  width: 50px;
}

.scroll__bar {
  height: 50px;
  background: red;
}
<div class="scroll">
  <div class="scroll__wrapper">
    <div class="scroll__elements">
      <div class="text">1</div>
      <div class="text">2</div>
      <div class="text">3</div>
      <div class="text">4</div>
      <div class="text">5</div>
      <div class="text">6</div>
      <div class="text">7</div>
      <div class="text">8</div>
      <div class="text">9</div>
      <div class="text">10</div>
      <div class="text">11</div>
      <div class="text">12</div>
      <div class="text">13</div>
      <div class="text">14</div>
      <div class="text">15</div>
      <div class="text">16</div>
      <div class="text">17</div>
      <div class="text">18</div>
      <div class="text">19</div>
      <div class="text">20</div>
      <div class="text">21</div>
      <div class="text">22</div>
      <div class="text">23</div>
      <div class="text">24</div>
      <div class="text">25</div>
      <div class="text">26</div>
      <div class="text">27</div>
      <div class="text">28</div>
      <div class="text">29</div>
      <div class="text">30</div>
    </div>
    <div class="scroll__bar">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam vitae ligula laoreet, iaculis dui sed, ultrices risus. Lorem ipsum dolor sit amet, consectetur adipiscing elit.</div>
  </div>
</div>

You need to set fit-content to min-width of your .container. This works with dynamic width.

See Stackblitz.

demo

body {
  width: 100%;
  height: 100%;
  margin: 0;
  font-family: Arial, Helvetica, sans-serif;
}

.component {
  display: block;
  width: 100%;
  overflow-x: auto;
}

.container {
  display: flex;
  flex-direction: column;
  min-width: fit-content;
}

.ruler {
  display: flex;
}

.text {
  flex: 1;
  min-width: 30px;
  text-align: center;
}

.text:nth-child(even) {
  background-color: #ddd;
}

.bar {
  position: relative;
  background-color: green;
  flex: 1;
  min-height: 30px;
}

.log {
  position: absolute;
  left: 30%;
  width: 30%;
  height: 100%;
  background-color: yellow;
  display: flex;
  justify-content: center;
  align-items: center;
}
<div class="component">
  <div class="container">
    <div class="ruler">
      <div class="text">1</div>
      <div class="text">2</div>
      <div class="text">3</div>
      <div class="text">4</div>
      <div class="text">5</div>
      <div class="text">6</div>
      <div class="text">7</div>
      <div class="text">8</div>
      <div class="text">9</div>
      <div class="text">10</div>
      <div class="text">11</div>
      <div class="text">12</div>
      <div class="text">13</div>
      <div class="text">14</div>
      <div class="text">15</div>
      <div class="text">16</div>
      <div class="text">17</div>
      <div class="text">18</div>
      <div class="text">19</div>
      <div class="text">20</div>
      <div class="text">21</div>
      <div class="text">22</div>
      <div class="text">23</div>
      <div class="text">24</div>
      <div class="text">25</div>
      <div class="text">26</div>
      <div class="text">27</div>
      <div class="text">28</div>
      <div class="text">29</div>
      <div class="text">30</div>
    </div>
    <div class="bar">
      <div class="log"><span>Some Log</span></div>
    </div>
  </div>
</div>

Related