That White Eyebrow Guy
That White Eyebrow Guy

Reputation: 569

Flex child does not take width of it's own children and cuts off hover

For some reason my complete understanding from CSS has been broken by the following snippet. My goal here is to show a hover over the whole .some-row-with-items element when I hover over it. For some reason unbeknownst to me, it cuts off the element right at the position of the scrollbar though and doesn't extend to cover all elements even though no explicit width is set. This is apparent by the red border added for visibility when you scroll horizontally.

Question here now is, how can I achieve a full hover over the full row?

* {
  box-sizing: border-box;
}

html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

.flex-main {
  display: flex;
  width: 100%;
  height: 100%;
  border: 2px solid blue;
}

.flex-main-content {
  flex: 1 1 100%;
  border: 2px solid green;
  display: flex;
  flex-direction: column;
  overflow: auto;
}

.some-long-row-with-items {
  display: flex;
  border: 1px solid red;
}

.some-long-row-with-items:hover {
  background: #eee;
}

.some-item {
  margin: 5px;
  width: 50px;
  height: 25px;
  border: 1px solid gray;
  flex: 0 0 50px;
}
<div class="flex-main">
  <div class="flex-main-content">
    <div class="nonflex">
      <div class="some-long-row-with-items">
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
      </div>
    </div>
  </div>
</div>

Upvotes: 3

Views: 1688

Answers (3)

AdityaSrivast
AdityaSrivast

Reputation: 1084

By default, flexbox takes up the width of its container, which in this case is 100% or 100vw. So when you apply hover effect on the .some-long-row-with-items, it causes background change over that amount of width.
flex: 0 0 50px style applied to .some-item makes the child elements take up the width of 50px, which would otherwise be auto. This is why the content inside the flexbox is overflowing out of it.
You can avoid this situation by:

  • setting width: max-content to the parent of the flexbox
  • setting width: max-content to flexbox
  • setting overflow: hidden to .some-long-row-with-items.

Upvotes: 1

kukkuz
kukkuz

Reputation: 42362

You can use an inline container by using display: inline-flex:

* {
  box-sizing: border-box;
}

html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

.flex-main {
  display: flex;
  width: 100%;
  height: 100%;
  border: 2px solid blue;
}

.flex-main-content {
  flex: 1 1 100%;
  border: 2px solid green;
  display: flex;
  flex-direction: column;
  overflow: auto;
}

.some-long-row-with-items {
  display: inline-flex; /* change here */
  border: 1px solid red;
}

.some-long-row-with-items:hover {
  background: #eee;
}

.some-item {
  margin: 5px;
  width: 50px;
  height: 25px;
  border: 1px solid gray;
  flex: 0 0 50px;
}
<div class="flex-main">
  <div class="flex-main-content">
    <div class="nonflex">
      <div class="some-long-row-with-items">
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
      </div>
    </div>
  </div>
</div>

Or you can use width: max-content on the flexbox container:

* {
  box-sizing: border-box;
}

html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

.flex-main {
  display: flex;
  width: 100%;
  height: 100%;
  border: 2px solid blue;
}

.flex-main-content {
  flex: 1 1 100%;
  border: 2px solid green;
  display: flex;
  flex-direction: column;
  overflow: auto;
}

.some-long-row-with-items {
  display: flex; 
  border: 1px solid red;
  width: max-content; /* added */
}

.some-long-row-with-items:hover {
  background: #eee;
}

.some-item {
  margin: 5px;
  width: 50px;
  height: 25px;
  border: 1px solid gray;
  flex: 0 0 50px;
}
<div class="flex-main">
  <div class="flex-main-content">
    <div class="nonflex">
      <div class="some-long-row-with-items">
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
        <div class="some-item"></div>
      </div>
    </div>
  </div>
</div>

Upvotes: 1

pitygacio
pitygacio

Reputation: 41

I tried it and apparently if you just remove flex: 0 0 50px; from your class .some-item works perfect, if I understand what you mean.

Upvotes: 0

Related Questions