skip to Main Content

In my attempt to create a responsive grid area with an svg image inside I have run into odd behaviour such as arbitrary grid area widths, and inability to have the image grow or shrink to a certain point than stop. The closest I have gotten is the following:

* {
    box-sizing: border-box;
}
body {
    margin: 0;
}

header {
    display: grid;
    grid-template-columns: auto 1fr;
    background-color: green;
    padding: 1rem;
}

img {
    width: 100%;
    max-width: 25vw;
    min-width: 12rem;
    background-color: pink;
}

div {
    background-color: red;
    text-align: center;
}

nav {
    background-color: yellow;
    grid-column: span 2;
}
<header>
  <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 324 413.28'%3E%3Crect class='655de5e2-44d3-4b5a-ae63-e6e7ec799246' x='18' y='18.12' width='288' height='324' fill='blue'/%3E%3C/svg%3E">
  <div>
    <h1>Heading</h1>
    <p>Text Line 1</p>
    <p>Text Line 2</p>
    <p>Text Line 3</p>
  </div>
  <nav>
    <a href="#">Menu Item 1</a>
    <a href="#">Menu Item 2</a>
    <a href="#">Menu Item 3</a>
    <a href="#">Menu Item 4</a>
    <a href="#">Menu Item 5</a>
    <a href="#">Menu Item 6</a>
  </nav>
</header>

I’ve tried height, min-height, max-height, and even using clamp within width with little success. Maybe I simply lack an understanding as some of the existing responses suggest, but not sure how to solve.

2

Answers


  1. If you wrap the image in a <div> and remove the width and height attributes from both <svg> and the <img> you let it up to the grid to control the sizing.

    Now, you can set whatever fits in your grid template, like grid-template-columns: 20% auto;.

    body {
      margin: 0;
    }
    
    header {
      display: grid;
      grid-template-columns: 20% auto;
      background-color: green;
      padding: 1rem;
    }
    
    header > div {
      background-color: pink;
      grid-column: 1;
      grid-row: 1;
    }
    
    header > section {
      background-color: red;
      grid-column: 2;
      grid-row: 1;
    }
    
    header > nav {
      background-color: yellow;
      grid-column: span 2;
      grid-row: 2;
    }
    <header>
      <div>
        <img src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMjQgNDEzLjI4Ij48cmVjdCB4PSIxOCIgeT0iMTguMTIiIHdpZHRoPSIyODgiIGhlaWdodD0iMzI0IiBmaWxsPSJibHVlIi8+PC9zdmc+">
      </div>
      <section>
        <h1>Heading</h1>
        <p>Text Line 1</p>
        <p>Text Line 2</p>
        <p>Text Line 3</p>
      </section>
      <nav>
        <a href="#">Menu Item 1</a>
        <a href="#">Menu Item 2</a>
        <a href="#">Menu Item 3</a>
        <a href="#">Menu Item 4</a>
        <a href="#">Menu Item 5</a>
        <a href="#">Menu Item 6</a>
      </nav>
    </header>
    Login or Signup to reply.
  2. The width of the image column is not arbitrary.

    The grid container is laying out the structure first. It is then laying out the items.

    This means that the first column is sized when the image is at its natural width (100%).

    When the item is then rendered at width: 50%, the browser doesn’t go back and re-size the column.

    So the column size isn’t arbitrary; it’s the natural width of the image.

    (This is arguably a bug or a CSS limitation.)

    Notice that this problem doesn’t exist when the image is at full width:

    * {
      box-sizing: border-box;
    }
    
    body {
      margin: 0;
    }
    
    header {
      display: grid;
      grid-template-columns: auto 1fr;
      background-color: green;
      padding: 1rem;
    }
    
    img {
      width: 100%;
      background-color: pink;
    }
    
    div {
      background-color: red;
    }
    
    nav {
      background-color: yellow;
      grid-column: span 2;
    }
    <header>
      <div style="background-color: blue">
        <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 324 413.28'%3E%3Crect class='655de5e2-44d3-4b5a-ae63-e6e7ec799246' x='18' y='18.12' width='288' height='324' fill='blue'/%3E%3C/svg%3E">
      </div>
      <div>
        <h1>Heading</h1>
        <p>Text Line 1</p>
        <p>Text Line 2</p>
        <p>Text Line 3</p>
      </div>
      <nav>
        <a href="#">Menu Item 1</a>
        <a href="#">Menu Item 2</a>
        <a href="#">Menu Item 3</a>
        <a href="#">Menu Item 4</a>
        <a href="#">Menu Item 5</a>
        <a href="#">Menu Item 6</a>
      </nav>
    </header>

    And it comes back when you try width: 150%:

    * {
      box-sizing: border-box;
    }
    
    body {
      margin: 0;
    }
    
    header {
      display: grid;
      grid-template-columns: auto 1fr;
      background-color: green;
      padding: 1rem;
    }
    
    img {
      width: 150%;
      background-color: pink;
    }
    
    div {
      background-color: red;
    }
    
    nav {
      background-color: yellow;
      grid-column: span 2;
    }
    <header>
      <div style="background-color: blue">
        <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 324 413.28'%3E%3Crect class='655de5e2-44d3-4b5a-ae63-e6e7ec799246' x='18' y='18.12' width='288' height='324' fill='blue'/%3E%3C/svg%3E">
      </div>
      <div>
        <h1>Heading</h1>
        <p>Text Line 1</p>
        <p>Text Line 2</p>
        <p>Text Line 3</p>
      </div>
      <nav>
        <a href="#">Menu Item 1</a>
        <a href="#">Menu Item 2</a>
        <a href="#">Menu Item 3</a>
        <a href="#">Menu Item 4</a>
        <a href="#">Menu Item 5</a>
        <a href="#">Menu Item 6</a>
      </nav>
    </header>

    Side Note

    Generally speaking, when working with CSS Grid and Flexbox, it’s not a good idea to make images the children of the container.

    In other words, it’s generally better to avoid images as grid or flex items.

    There are just too many bugs and rendering variations among different browsers.

    In many cases, simply putting the image in a div (making the div the grid item) solves the problem.

    Avoid images as grid or flex items:

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search