Bradley Odell
Bradley Odell

Reputation: 1258

Flexbox: Restrict content to size of container, overflow if needed

I'm having some trouble getting Flexbox to prioritizing the element sizing correctly.

In general there are two things that control sizing of elements:

  1. The container: Pushes in against the content and may cause the content to overflow (if there is too much).
  2. The content: Pushes out against the container and may cause the container to resize.

This is Layout 101 and, to this day, I'm still confused why HTML/CSS has no way to directly control the priority of element sizing. I feel like I just have to throw stuff together and hope that the browser renders the sizing in the way I want it to. Anyway, I digress...

.collapse {
  display: none !important;
}
.horizontal-fill {
  width: 100%;
  min-width: 100%;
  box-sizing: border-box;
}
.container {
  text-align: center;
}
.inline-center {
  display: inline-block;
  min-width: 600px;
  text-align: left;
}
.table-container {
  border-color: black;
  border-width: 1px;
  border-style: solid;
  padding: 5px;
  background-color: lightgray;
}
.table-controls {
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  align-content: stretch;
  align-items: baseline;
}
.table-controls-search {
  min-width: 150px;
  width: 25%;
  margin-right: 5px;
}
.table-controls-results {
  white-space: nowrap;
  text-shadow: 0px 0px 3px white;
  font-weight: bolder;
  font-size: smaller;
  margin-right: 5px;
}
.table-controls-navigation {
  margin-left: auto;
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  align-content: stretch;
  align-items: stretch;
  flex: 1 1 0;
}
.table-controls-navigation button {
  border-radius: 0px;
}
.table-controls-pages {
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  align-content: stretch;
  align-items: stretch;
  flex: 1 1 0;
  /** Enabling this causes the page buttons to start overflowing */
  /** which is the desired behavior */
  /** width: 0px; */
  /** However, doing so causes the page buttons to float to the left */
  /** even when the page buttons don't overflow. */
  overflow-x: hidden;
}
<div class="container">
  <div class="inline-center">
    <div class="table-container">
      <div class="table-controls">
        <div class="table-controls-search">
          <input class="horizontal-fill" type="text" size="1" placeholder="Search/Filter">
        </div>
        <div class="table-controls-results">
          <span>Results: </span><span class="table-controls-result">25</span>
        </div>
        <div class="table-controls-navigation">
          <div>
            <button disabled="">First</button>
          </div>
          <div>
            <button disabled="">Previous</button>
          </div>
          <div class="table-controls-pages">
            <div class="table-controls-page">
              <button disabled="">1</button>
            </div>
            <div class="table-controls-page">
              <button>2</button>
            </div>
            <div class="table-controls-page">
              <button>3</button>
            </div>
            <!-- These comments are used to comment out a bunch of the page buttons -->
            <!-- Doing so when (width: 0px) results in the page buttons continuing to "float" left -->
            <!-- -->
            <div class="table-controls-page">
              <button>4</button>
            </div>
            <div class="table-controls-page">
              <button>5</button>
            </div>
            <div class="table-controls-page">
              <button>6</button>
            </div>
            <div class="table-controls-page">
              <button>7</button>
            </div>
            <div class="table-controls-page">
              <button>8</button>
            </div>
            <div class="table-controls-page">
              <button>9</button>
            </div>
            <div class="table-controls-page">
              <button>10</button>
            </div>
            <!-- -->
          </div>
          <div>
            <button>Next</button>
          </div>
          <div>
            <button>Last</button>
          </div>
        </div>
      </div>
    </div>
  </div>

Please excuse the large amount of code.

The main focus is on the "page buttons" on the left side of the bar. I want the page buttons to fill the remaining space and overflow if they're unable to fit. (Only the numbered buttons!) But if they are able to fit without overflowing, then all the buttons need to be aligned to the right.

I can't seem to get the layout to have this behavior. Either the buttons fail to overflow and end up resizing the container, or the (numbered) buttons just disappear completely.

Upvotes: 1

Views: 2145

Answers (1)

Bradley Odell
Bradley Odell

Reputation: 1258

I was able to solve this by changing flex-wrap: nowrap to flex-wrap: wrap in the CSS .table-controls-navigation.

Also, flex: 1 1 0 was taken out of .table-controls-navigation.

It appears that this was preventing any children from overflowing because it forced the container to resize to fit all content.

.collapse {
  display: none !important;
}
.horizontal-fill {
  width: 100%;
  min-width: 100%;
  box-sizing: border-box;
}
.container {
  text-align: center;
}
.inline-center {
  display: inline-block;
  min-width: 600px;
  text-align: left;
}
.table-container {
  border-color: black;
  border-width: 1px;
  border-style: solid;
  padding: 5px;
  background-color: lightgray;
}
.table-controls {
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  align-content: stretch;
  align-items: baseline;
}
.table-controls-search {
  min-width: 150px;
  width: 25%;
  margin-right: 5px;
}
.table-controls-results {
  white-space: nowrap;
  text-shadow: 0px 0px 3px white;
  font-weight: bolder;
  font-size: smaller;
  margin-right: 5px;
}
.table-controls-navigation {
  margin-left: auto;
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  align-content: stretch;
  align-items: stretch;
}
.table-controls-navigation button {
  border-radius: 0px;
}
.table-controls-pages {
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  align-content: stretch;
  align-items: stretch;
  flex: 1 1 0;
  /** Enabling this causes the page buttons to start overflowing */
  /** which is the desired behavior */
  /** width: 0px; */
  /** However, doing so causes the page buttons to float to the left */
  /** even when the page buttons don't overflow. */
  overflow-x: hidden;
}
<div class="container">
  <div class="inline-center">
    <div class="table-container">
      <div class="table-controls">
        <div class="table-controls-search">
          <input class="horizontal-fill" type="text" size="1" placeholder="Search/Filter">
        </div>
        <div class="table-controls-results">
          <span>Results: </span><span class="table-controls-result">25</span>
        </div>
        <div class="table-controls-navigation">
          <div>
            <button disabled="">First</button>
          </div>
          <div>
            <button disabled="">Previous</button>
          </div>
          <div class="table-controls-pages">
            <div class="table-controls-page">
              <button disabled="">1</button>
            </div>
            <div class="table-controls-page">
              <button>2</button>
            </div>
            <div class="table-controls-page">
              <button>3</button>
            </div>
            <!-- These comments are used to comment out a bunch of the page buttons -->
            <!-- Doing so when (width: 0px) results in the page buttons continuing to "float" left -->
            <!--
            <div class="table-controls-page">
              <button>4</button>
            </div>
            <div class="table-controls-page">
              <button>5</button>
            </div>
            <div class="table-controls-page">
              <button>6</button>
            </div>
            <div class="table-controls-page">
              <button>7</button>
            </div>
            <div class="table-controls-page">
              <button>8</button>
            </div>
            <div class="table-controls-page">
              <button>9</button>
            </div>
            <div class="table-controls-page">
              <button>10</button>
            </div>
            -->
          </div>
          <div>
            <button>Next</button>
          </div>
          <div>
            <button>Last</button>
          </div>
        </div>
      </div>
    </div>
  </div>

Upvotes: 1

Related Questions