Search code examples
csscss-grid

CSS grid - How to stop extraneous text from creating an auto row?


I am trying to style some pre-existing content and I can't edit the HTML. There is a random '&nbsp' in the code that is causing CSS grid to create a new row. How to stop the auto row when there is no html or class to target?

Edit: Some rows have 2 items and some have 3.

td.product-name {
     display: grid;
     grid-template-columns: 60px 3fr;
     grid-template-rows: auto;
     grid-template-areas: " left righta " " left rightb " "left rightc";
         grid-auto-flow: dense; 
     border: 1px solid;
}
 td.product-name span {
  
 border: 1px solid;
 }
.product-image {
grid-area: left;
}
 .product-name {
     grid-area: righta;
}
 .product-quantity {
     grid-area: rightb;
}
 .variation {
     grid-area: rightc;
}
<table>
<tr class="cart_item">
  <td class="product-name">
    <span class="product-image"><img width="50" height="50" src="https://i.imgur.com/1o3KcN6.png"></span>
    <span class="product-name">Product 1</span>
    &nbsp; <- remove the row created by this nbsp;
    <span class="product-quantity">QTY 1</span>
    <span class="variation">var 1 EDIT: This row doesn't always have a value.</span>  
  </td>
  <td class="product-total">
    <span class="amount"><bdi><span class="woocommerce-Price-currencySymbol">$</span>48</bdi>
    </span>
  </td>
</tr>
<tr class="cart_item">
  <td class="product-name">
    <span class="product-image"><img width="50" height="50" src="https://i.imgur.com/1o3KcN6.png"></span>
    <span class="product-name">Product 2</span>
    &nbsp; <- remove the row created by this nbsp;
    <span class="product-quantity">QTY 2</span>
     
  </td>
  <td class="product-total">
    <span class="amount"><bdi><span class="woocommerce-Price-currencySymbol">$</span>58</bdi>
    </span>
  </td>
</tr>
</table>


Solution

  • One option would be to make it an explicit row and give it zero height (grid-template-rows: 1fr 1fr 1fr 0;):

    UPDATE: I've updated the answer based on the new information. Given that the .variation span may or may not exist, I've introduced the has() selector to check for this. Note that the has() selector doesn't have perfect support yet, though it's pretty good now in the latest browsers.

    td.product-name {
      display: grid;
      grid-template-columns: 60px 3fr;
      grid-template-rows: 1fr 1fr 0;
      grid-template-areas: " left righta " " left rightb ";
      border: 1px solid;
    }
    
    td.product-name:has(.variation) {
      grid-template-rows: 1fr 1fr 1fr 0;
      grid-template-areas: " left righta " " left rightb " "left rightc";
    }
     
    td.product-name span {
      border: 1px solid;
    }
    
    .product-image {
      grid-area: left;
    }
    
    .product-name {
      grid-area: righta;
    }
    
    .product-quantity {
      grid-area: rightb;
    }
    
    .variation {
      grid-area: rightc;
    }
    <table>
    <tr class="cart_item">
      <td class="product-name">
    <span class="product-image"><img width="50" height="50" src="https://i.imgur.com/1o3KcN6.png"></span>
    <span class="product-name">Product 1</span>
    &nbsp;
    <span class="product-quantity">QTY 1</span>
    <span class="variation">var 1</span>  
      </td>
      <td class="product-total">
    <span class="amount"><bdi><span class="woocommerce-Price-currencySymbol">$</span>48</bdi>
    </span>
      </td>
    </tr>
    <tr class="cart_item">
      <td class="product-name">
    <span class="product-image"><img width="50" height="50" src="https://i.imgur.com/1o3KcN6.png"></span>
    <span class="product-name">Product 2</span>
    &nbsp;
    <span class="product-quantity">QTY 2</span>
      </td>
      <td class="product-total">
    <span class="amount"><bdi><span class="woocommerce-Price-currencySymbol">$</span>58</bdi>
    </span>
      </td>
    </tr>
    </table>

    UPDATE2

    Because has() currently doesn't work in Firefox, there is a compromise option that keeps every browser happy. It's not the perfect solution, but at least seems to provide an acceptable result in every browser.

    td.product-name {
      display: grid;
      grid-template-columns: 60px 3fr;
      grid-template-rows: 1fr 1fr auto 0;
      grid-template-areas: " left righta " " left rightb " "left rightc";
      border: 1px solid;
    }
     
    td.product-name span {
      border: 1px solid;
    }
    
    .product-image {
      grid-area: left;
    }
    
    .product-name {
      grid-area: righta;
    }
    
    .product-quantity {
      grid-area: rightb;
    }
    
    .variation {
      grid-area: rightc;
    }
    <table>
    <tr class="cart_item">
      <td class="product-name">
        <span class="product-image"><img width="50" height="50" src="https://i.imgur.com/1o3KcN6.png"></span>
        <span class="product-name">Product 1</span>
        &nbsp;
        <span class="product-quantity">QTY 1</span>
        <span class="variation">var 1</span>  
      </td>
      <td class="product-total">
        <span class="amount"><bdi><span class="woocommerce-Price-currencySymbol">$</span>48</bdi>
        </span>
      </td>
    </tr>
    <tr class="cart_item">
      <td class="product-name">
        <span class="product-image"><img width="50" height="50" src="https://i.imgur.com/1o3KcN6.png"></span>
        <span class="product-name">Product 2</span>
        &nbsp;
        <span class="product-quantity">QTY 2</span>
      </td>
      <td class="product-total">
        <span class="amount"><bdi><span class="woocommerce-Price-currencySymbol">$</span>58</bdi>
        </span>
      </td>
    </tr>
    </table>

    So instead of an extra row at the bottom, there is just an empty cell on the right when there's no variations span.