Danield
Danield

Reputation: 125641

How to shrink-wrap a css grid?

Assuming the following grid layout:

div {
  display: grid;
  grid-template-columns: auto auto;
  grid-row-gap: 1em;
  border: 5px solid green;
  margin: 50px;
}
h3 {
  grid-column: 1 / -1;
  margin: 0;
}
span {
  background-color: pink;
}
h3, span {
  padding: 0.5em;
}
span + span {
  background-color: salmon;
}
<div>
  <h3>1. A heading here</h3>
  <span>some text here</span>
  <span>some  more text here as well thanks</span>
</div>

I would like to 'shrink-wrap' the grid items so that

1) the maximum width of the grid will only be as wide as the content, but

2) if there's not enough room for the content - the items will wrap accordingly.

In the above demo, the first constraint fails - the grid columns stretch to fit their respective content and all the extra viewport width is split equally (added) between the columns.

Codepen demo - (Resize to see what I'm talking about)

I've tried a few approaches to fix this, but they all 'shrink-wrap' the grid items as apposed to the actual grid itself:

1) Set max-content as the track length instead of auto

grid-template-columns: max-content max-content;

div {
  display: grid;
  grid-template-columns: max-content max-content;
  grid-row-gap: 1em;
  border: 5px solid green;
  margin: 50px; 
}
h3 {
  grid-column: 1 / -1;
  margin: 0;
}
span {
  background-color: pink;
}
h3, span {
  padding: 0.5em;
}
span + span {
  background-color: salmon;
}
<div>
  <h3>1. A heading here</h3>
  <span>some text here</span>
  <span>some text here</span>
</div>

2) Set justify-content: flex-start; on the grid container

div {
  display: grid;
  grid-template-columns: auto auto;
  grid-row-gap: 1em;
  border: 5px solid green;
  margin: 50px; 
  justify-content: flex-start;
}
h3 {
  grid-column: 1 / -1;
  margin: 0;
}
span {
  background-color: pink;
}
h3, span {
  padding: 0.5em;
}
span + span {
  background-color: salmon;
}
<div>
  <h3>1. A heading here</h3>
  <span>some text here</span>
  <span>some text here</span>
</div>

3) Add a bogus 3rd column which fills the remaining viewport width with an empty third column:

grid-template-columns: auto auto 1fr;

div {
  display: grid;
  grid-template-columns: auto auto 1fr;
  grid-row-gap: 1em;
  border: 5px solid green;
  margin: 50px; 
}
h3 {
  grid-column: 1 / -1;
  margin: 0;
}
span {
  background-color: pink;
}
h3, span {
  padding: 0.5em;
}
span + span {
  background-color: salmon;
}
<div>
  <h3>1. A heading here</h3>
  <span>some text here</span>
  <span>some text here</span>
</div>

So how would I 'shrink-wrap' the grid?

Upvotes: 2

Views: 7119

Answers (1)

Danield
Danield

Reputation: 125641

Setting display: grid on an element causes it to generate a block-level grid container box.

This is what causes the grid to fill the viewport width and stretch the items accordingly.

That being the case, we can stop the grid from stretching by setting one of the following on the grid container:

1) display: inline-grid;

div {
  display: inline-grid; /* <-- modified */
  grid-template-columns: auto auto;
  grid-row-gap: 1em;
  border: 5px solid green;
  margin: 50px;
}
h3 {
  grid-column: 1 / -1;
  margin: 0;
}
span {
  background-color: pink;
}
h3, span {
  padding: 0.5em;
}
span + span {
  background-color: salmon;
}
<div>
  <h3>1. A heading here</h3>
  <span>some text here</span>
  <span>some text here</span>
</div>

2) float: left; /* or right */

div {
  display: grid;
  float: left; /* <-- added */
  grid-template-columns: auto auto;
  grid-row-gap: 1em;
  border: 5px solid green;
  margin: 50px;
}
h3 {
  grid-column: 1 / -1;
  margin: 0;
}
span {
  background-color: pink;
}
h3, span {
  padding: 0.5em;
}
span + span {
  background-color: salmon;
}
<div>
  <h3>1. A heading here</h3>
  <span>some text here</span>
  <span>some text here</span>
</div>

3) position: absolute;

div {
  display: grid;
  position: absolute; /* <--- added */
  grid-template-columns: auto auto;
  grid-row-gap: 1em;
  border: 5px solid green;
  margin: 50px;
}
h3 {
  grid-column: 1 / -1;
  margin: 0;
}
span {
  background-color: pink;
}
h3, span {
  padding: 0.5em;
}
span + span {
  background-color: salmon;
}
<div>
  <h3>1. A heading here</h3>
  <span>some text here</span>
  <span>some text here</span>
</div>

Alternatively, we could set width: fit-content on grid container.

div {
  display: grid;
  grid-template-columns: auto auto;
  grid-row-gap: 1em;
  border: 5px solid green;
  margin: 50px; 
  width: fit-content; /* <-- added */
}
h3 {
  grid-column: 1 / -1;
  margin: 0;
}
span {
  background-color: pink;
}
h3, span {
  padding: 0.5em;
}
span + span {
  background-color: salmon;
}
<div>
  <h3>1. A heading here</h3>
  <span>some text here</span>
  <span>some text here</span>
</div>

Upvotes: 1

Related Questions