Home > Net >  Use CSS Grid layout in a specific case
Use CSS Grid layout in a specific case

Time:04-08

I could get the result I want in many other ways, but I want to understand if it is possible to fix the layout while keeping the grid system.

Check the result first to get a better understanding

$(document).ready(function() {
  $('#opt1').on('click', function() {
    $('.item').css('grid-template-columns', 'minmax(110px, 1fr) auto');
  });

  $('#opt2').on('click', function() {
    $('.item').css('grid-template-columns', 'minmax(110px, 1fr) max-content');
  });

  $('#opt3').on('click', function() {
    $('.item').css('grid-template-columns', 'auto 1fr');
  });
  
});
.container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 25px 25px;
  margin-top: 25px;
}

.item {
  position: relative;
  display: grid;
  grid-template-columns: minmax(110px, 1fr) auto;
  background-color: #2f3138;
  color: #ffffff;
  padding: 15px;
}

.description {
  display: grid;
  grid-template-rows: auto 25px;
}

.price {
  width: 100%;
  font-size: 22px;
  line-height: 25px;
  text-align: right;
}


/* styles not important */

.item::before {
  position: absolute;
  font-family: monospace;
  font-size: 18px;
  font-weight: bold;
  color: #ffffff;
  border-radius: 50%;
  background-color: #000000;
  width: 25px;
  height: 25px;
  line-height: 25px;
  text-align: center;
  border: solid 5px #2f3138;
  top: -8px;
  right: -8px;
}

.item:nth-child(1)::before {
  content: "1";
}

.item:nth-child(2)::before {
  content: "2";
}

.item:nth-child(3)::before {
  content: "3";
}

.item:nth-child(4)::before {
  content: "4";
}

input[type="button"] {
  background-color: #000000;
  border: solid 2px #2f3138;
  color: #ffffff;
  outline: none;
  margin: 5px 15px 5px 0px;
  padding: 5px 15px 8px 15px;
  font-family: monospace;
  cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<input id="opt1" type="button" value="Original: minmax(110px, 1fr) auto" />
<input id="opt2" type="button" value="option 2: minmax(110px, 1fr) max-content" />
<input id="opt3" type="button" value="option 3: auto 1fr" />

<div >

  <div >
    <img src="https://placeimg.com/100/120/any" />
    <div >
      <span>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam sit amet mauris semper, interdum lacus a, fermentum risus.
      </span>
      <div >€ 3.33</div>
    </div>
  </div>

  <div >
    <div >
      <span>Short Text</span>
      <div >€ 3.33</div>
    </div>
  </div>

  <div >
    <img src="https://placeimg.com/100/121/any" />
    <div >
      <span>Short Text</span>
      <div >€ 3.33</div>
    </div>
  </div>


  <div >
    <div >
      <span>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam sit amet mauris semper, interdum lacus a, fermentum risus.
      </span>
      <div >€ 3.33</div>
    </div>
  </div>


</div>

The layout represents a list of items. The HTML is generated on the server side, and I can have an item with the image and an item without an image. My goal is to get all items with the text always left aligned and the price on the right.

The key is this grid-template-columns: minmax (110px, 1fr) auto; the text will be auto with the image and 1fr without image. It always occupies the space it needs, but in item 3 the text is short and space it needs is little, I would like it to extend as in item 1.

The javascript part to show some attempts that still generate non optimal results.

I hope I was clear. Thank you

CodePudding user response:

Rely on implicit grid creation. Define your template for the text and price only then an extra column will be created for the image if there:

.container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 25px;
  margin-top: 25px;
}

.item {
  position: relative;
  display: grid;
  grid-template-columns: 1fr;
  grid-auto-columns: 110px; /* this is the width of the extra column */
  background-color: #2f3138;
  color: #ffffff;
  padding: 15px;
}

img {
  grid-column-end:-2; /* create an implicit column at the beginning */
}

.description {
  display: grid;
  grid-template-rows: auto 25px;
}

.price {
  font-size: 22px;
  line-height: 25px;
  text-align: right;
}


/* styles not important */

.item::before {
  position: absolute;
  font-family: monospace;
  font-size: 18px;
  font-weight: bold;
  color: #ffffff;
  border-radius: 50%;
  background-color: #000000;
  width: 25px;
  height: 25px;
  line-height: 25px;
  text-align: center;
  border: solid 5px #2f3138;
  top: -8px;
  right: -8px;
}

.item:nth-child(1)::before {
  content: "1";
}

.item:nth-child(2)::before {
  content: "2";
}

.item:nth-child(3)::before {
  content: "3";
}

.item:nth-child(4)::before {
  content: "4";
}

input[type="button"] {
  background-color: #000000;
  border: solid 2px #2f3138;
  color: #ffffff;
  outline: none;
  margin: 5px 15px 5px 0px;
  padding: 5px 15px 8px 15px;
  font-family: monospace;
  cursor: pointer;
}
<div >

  <div >
    <img src="https://placeimg.com/100/120/any" />
    <div >
      <span>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam sit amet mauris semper, interdum lacus a, fermentum risus.
      </span>
      <div >€ 3.33</div>
    </div>
  </div>

  <div >
    <div >
      <span>Short Text</span>
      <div >€ 3.33</div>
    </div>
  </div>

  <div >
    <img src="https://placeimg.com/100/121/any" />
    <div >
      <span>Short Text</span>
      <div >€ 3.33</div>
    </div>
  </div>


  <div >
    <div >
      <span>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam sit amet mauris semper, interdum lacus a, fermentum risus.
      </span>
      <div >€ 3.33</div>
    </div>
  </div>


</div>

  • Related