Two equal width columns (where the width is set by the longest one) and a third one fills the remaining space

Viewed 92

I want to make a layout like this, using CSS Grid if possible but open to other possibilities:

enter image description here

Basically, I want to have a container .grid that contains 3 elements (input, btn1, btn2). Firstly, btn1 and btn2 width should be the same and is determine by whichever element needs more space (i.e longer content). After that, the remaining element (input) should take all what is left. I came up with this snippet but for sure it cannot work.

.grid {
  display: grid;
  grid-template-columns: auto 1fr 1fr;
}
<div class="grid">
  <input />
  <button>Foo</button>
  <button>Bar Bar Bar</button>
</div>

What is a good way to achieve this using CSS only?

2 Answers

Here is a hack (yes a hack!) that relies on the fact that you know the container width.

In the below, I will consider a full-page container (width defined using 100vw)

.grid {
  display: grid;
  margin:50px 5px;
  grid-template-columns:1fr auto;
}
/* they will overlap so the longest one will define the size of auto*/
button {
  grid-column:2;
  grid-row:1;
}

/* we translate the first one to disable the overlap*/
button:first-of-type {
  transform:translateX(-100%);
}

input {
  /* 100vw - 10px = width of the grid container 
     100% is the width of the 1fr
     ((100vw - 10px) - 100%) will be the width of the buttons
  */
  width:calc(100% - ((100vw - 10px) - 100%));
  box-sizing:border-box;
}

body {
 margin:0;
}
<div class="grid">
  <input >
  <button>Foo</button>
  <button>Bar Bar Bar</button>
</div>

Use a nested grid container for the buttons.

.grid {
  display: grid;
  grid-template-columns: 1fr auto; /* see note 1 */
}

.button-container {
  display: grid;
  grid-template-columns: 1fr 1fr; /* see note 2 */
}
<div class="grid">
  <input />
  <div class="button-container">
    <button>Foo</button>
    <button>Bar Bar Bar</button>
  </div>
</div>
<br>
<div class="grid">
  <input />
  <div class="button-container">
    <button>Foo</button>
    <button>Bar Bar Bar Bar Bar Bar</button>
  </div>
</div>
<br>
<div class="grid">
  <input />
  <div class="button-container">
    <button>Foo</button>
    <button>Bar Bar Bar Bar Bar Bar Bar Bar Bar</button>
  </div>
</div>

Notes:

  1. 1fr on the first column consumes all available horizontal space, pinning the second column to the right as much as possible.

  2. 1fr 1fr on the nested columns causes the horizontal space in the sub-container to be equally divided, regardless of content width.

Related