skip to Main Content

I have a header with a couple of icons, a title, and a search box that animates the input field when I click on the search button. Everything works great except when I go to smaller screens. The intended effect I would like is that on a smaller screen the search field would expand all the way to the edge to hide the icon and title on the left, but I can’t get the input field to accept the max-width property.

I have tried setting a fixed width on the search field, and messing around with the flex-basis and flex-shrink on the different containers, but nothing seems to work. I am open to simplifying the markup seeing as I have a flex within a flex within a flex… but it seemed to be the best way to get everything centered, responsive and spaced neatly.

.wrapper {
  background-color: #DDD;
  overflow: hidden;
  resize: both;
}

header {
  background-color: #AAA;
  justify-content: space-between;
  margin: 0 auto;
  max-width: 1000px;
  padding: 0 2rem;
}

.flex-center {
  align-items: center;
  display: flex;
  gap: 1rem;
}

.icon {
  height: 2rem;
  width: 2rem;
}

.icon {
  flex: 0 0 auto;
  border: none;
  background-color: red;
}

.search-field {
  background-color: green;
  border: none;
  flex: 0 0 auto;
  height: 2rem;
  outline: none;
  padding: 0;
  transition: 0.3s;
  width: 0;
}

.search-field:focus {
  max-width: 300px;
  width: 100%;
}

.search {
  justify-content: flex-end;
}
<div class="wrapper">
  <header class="flex-center">
    <div class="flex-left flex-center">
      <button class="icon"></button>
      <h1 class="title">Title</h1>
    </div>
    <div class="flex-right flex-center">
      <form class="search-form flex-center">
        <input id="search-field" class="search-field" type="search">
        <label class="icon" for="search-field"></label>
      </form>
      <button class="icon"></button>
    </div>
  </header>
</div>

I am also open to vanilla JavaScript solutions if there is no other way to do this in CSS.

2

Answers


  1. Chosen as BEST ANSWER

    I figured it out. I removed display: flex from the header and positioned the left div with position: absolute to take it out of the flow of the document. This way I can expand the right flex box full width. This is the markup and css I ended up with. From here I can just add a media query to make it 100% of the width when the screen size gets small enough, and I avoid having to use the has: pseudo class.

    .wrapper {
      background-color: #DDD;
      overflow: hidden;
      resize: both;
    }
    
    header {
      background-color: #AAA;
      justify-content: space-between;
      margin: 0 auto;
      max-width: 1000px;
      padding: 2rem;
      position: relative;
    }
    
    .title {
      font-size: 2rem;
      line-height: 2rem;
      margin: 0;
    }
    
    .flex-center {
      align-items: center;
      display: flex;
      gap: 1rem;
    }
    
    .left {
      left: 2rem;
      position: absolute;
      top: 2rem;
      z-index: 1;
    }
    
    .right {
      flex: 1;
      justify-content: flex-end;
      position: relative;
      z-index: 2;
    }
    
    .icon {
      border: none;
      background-color: red;
      flex: 0 0 auto;
      height: 2rem;
      width: 2rem;
    }
    
    .search-btn {
      background-color: blue;
    }
    
    .search-field {
      background-color: green;
      border: none;
      height: 2rem;
      outline: none;
      padding: 0;
      transition: 0.3s;
      width: 0;
    }
    
    .search-field:focus {
      width: 200px;
    }
    
    @media only screen and (max-width: 600px) {
      .search-field:focus {
        width: 100%;
      }
    }
    <div class="wrapper">
      <header>
        <div class="left flex-center">
          <button class="icon"></button>
          <h1 class="title">Title</h1>
        </div>
        <form class="right flex-center">
          <input id="search-field" class="search-field" type="search">
          <label class="icon search-btn" for="search-field"></label>
          <button class="icon"></button>
        </form>
      </header>
    </div>


  2. To see the result you have to check from 600px viewport width or below. And the :has() pseudo-class has limited browser support (it doesn’t work in Firefox).

    Caniuse

    Necessary details are included with comments inside the codes.

    .wrapper {
        background-color: #DDD;
        overflow: hidden;
        resize: both;
    }
    
    header {
        background-color: #AAA;
        justify-content: space-between;
        margin: 0 auto;
        max-width: 1000px;
        padding: 0 2rem;
    }
    
    .flex-center {
        align-items: center;
        display: flex;
        gap: 1rem;
    }
    
    .icon {
        height: 2rem;
        width: 2rem;
    }
    
    .icon {
        flex: 0 0 auto;
        border: none;
        background-color: red;
    }
    
    .search-field {
        background-color: green;
        border: none;
        flex: 0 0 auto;
        height: 2rem;
        outline: none;
        padding: 0;
        transition: 0.3s;
        width: 0;
    }
    
    .search-field:focus {
        max-width: 300px;
        width: 100%;
    }
    
    .search {
        justify-content: flex-end;
    }
    
    /* new added codes ======================================================= */
    
    /* You can set the screen width from when you want the input to cover the total left side */
    @media only screen and (max-width: 600px){
        /* hiding the title and the icon when the input(search-field) is on focus in smaller screens */
        header:has(.search-field:focus) .flex-left{
            display: none;
        }
    
        /* setting the full width for the flex-right contents */
        header:has(.search-field:focus) .flex-right{
            width: 100%;
        }
    
        header:has(.search-field:focus) .flex-right form{
            width: 100%;
        }
    
        /* unsetting the max-width of the input so that it can take 100% of the width instead of the 300px max-width restriction */
        .search-field:focus {
            max-width: unset;
        }
    
        /* this height is depending upon the title */
        header:has(.search-field:focus){
            height: 5rem;
        }
    }
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
        <div class="wrapper">
            <header class="flex-center">
              <div class="flex-left flex-center">
                <button class="icon"></button>
                <h1 class="title">Title</h1>
              </div>
              <div class="flex-right flex-center">
                <form class="search-form flex-center">
                  <input id="search-field" class="search-field" type="search">
                  <label class="icon" for="search-field"></label>
                </form>
                <button class="icon"></button>
              </div>
            </header>
          </div>
    </body>
    </html>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search