You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React应用中搜索栏响应式宽度调整问题求助

React Header搜索框弹性伸缩问题解决方案

问题描述

我在React项目的Header组件中间区域有一个class为search-text的搜索输入框,希望设置其默认宽度为600px,屏幕缩小时自动缩小至最小宽度100px,屏幕变大时自然恢复至600px,模仿YouTube头部搜索栏的flex伸缩效果,但尝试多种方法后均无效,搜索栏始终保持600px不收缩。

相关React代码

import React from 'react'
import './Header.scss'
import logo from './assets/youtube-logo.svg'
import menu from './assets/hamburger-menu.svg'
import glass from './assets/search.svg'
import mike from './assets/voice-search-icon.svg'
import upload from './assets/upload.svg'
import bell from './assets/notifications.svg'
import pin from './assets/nob.jpeg'

const Header = ({toggler}) => {
  return (
    <div className='header'>
      <div className='left-section'>
        <button className='menu'> 
          <img className='menu-icon' onClick={toggler} src={menu}/>
        </button>
        <a href='/'>
        <img className='you-logo' src={logo}/>
        </a>
      </div>
      <div className='middle-section'>
        <form className='search-form'>
          <div className='search-bar'>
            <input className='search-text' type='search' placeholder='Search'/>
            <button className='search-but'>
                <img className='search-icon' src={glass}/>
                <div className='tooltip'>Search</div>
            </button>
          </div>
          <button type='button' className='voice-but'>
            <img className='voice' src={mike}/>
            <div className='tooltip'>Search with your voice</div>
          </button>
        </form>
      </div>
      <div className='right-section'>
        <button className='upload-container'>
          <img className='upload' src={upload}/>
          <div className='tooltip'>Create</div>
        </button>
        <button className='notify'>
          <img className='notify-icon' src={bell}/>
          <div className='notify-count'>3</div>
          <div className='tooltip'>Notifications</div>
        </button>
        <img className='pin-girl' src={pin}/>
      </div>
    </div>
  )
}

export default Header

相关SCSS样式

.header {
  display: flex;
  justify-content: space-between;
  padding: 0.5rem 0rem 0.5rem 0.5rem;
  align-items: center;
  width: 100vw;
  gap: 70px;
  position: fixed;
  top: 0;
  z-index: 12;
  .left-section {
      display: flex;
      align-items: center;
      flex-shrink: 0;
      .menu {
          padding: 8px 8px;
          border-radius: 50%;
          border: none;
          display: flex;
          background-color: white;
          margin-right: 12px;
          cursor: pointer;
          .menu-icon {
              height: 25px;
              width: 25px;
          }
          &:hover {
              background-color: rgb(230, 230, 230);
          }
      }
      a {
          .you-logo {
              height: 25px;
          }
      }
  }
  .middle-section {
      display: flex;
      flex-direction: row;
      justify-content: center;
      align-items: center;
      .search-form{
          display: flex;
          flex-direction: row;
          .search-bar {
              display: flex;
              .search-text {
                  flex-grow: 1;
                  flex-shrink: 1;
                  width: 600px;
                  min-width: 150px;
                  border-bottom-left-radius: 50px;
                  border-top-left-radius: 50px;
                  box-shadow: inset 0 2px 4px 0 rgba(0, 0, 0, 0.06);
                  border: solid 1px;
                  border-color: rgb(207, 207, 207);
                  padding: 0.5rem 1rem;
                  font-size: large;
                  outline: none;
                  z-index: 5;
                  &:focus {
                      box-shadow: 0 0 0 0.3px rgb(0, 47, 255);
                  }  
              }
              .search-but {
                  padding: 2px 4px; 
                  border-top-right-radius: 50px;
                  border-bottom-right-radius: 50px;
                  border: solid 1px;
                  border-color: rgb(207, 207, 207);
                  border-left: none;
                  display: flex;
                  align-items: center;
                  justify-content: center;
                  width: 50px;
                  z-index: 4;
                  cursor: pointer;
                  position: relative;
                  &:hover {
                      background-color:rgb(230, 230, 230);
                  }
                  &:hover .tooltip {
                      font-family: sans-serif;
                      position: absolute;
                      background-color: grey;
                      color: white;
                      padding: 10px 6px;
                      border-radius: 2px;
                      font-size: 12px;
                      transition: opacity 0.15s;
                      pointer-events: none;
                      white-space: nowrap;
                      display: block;
                      bottom: -50px;
                      opacity: 0.8;
                  }
                  .search-icon {
                      height: 25px;
                      width: 25px;
                  }
                  .tooltip {
                      display: none;
                  }
              }
          }
          .voice-but {
              padding: 8px 8px;
              border-radius: 50%;
              border: none;
              display: flex;
              margin-left: 15px;
              position: relative;
              cursor: pointer;
              transition: background-color 0.3s;
              &:hover {
                  background-color:rgb(200, 200, 200);
              }
              &:hover .tooltip {
                  font-family: sans-serif;
                  position: absolute;
                  background-color: grey;
                  color: white;
                  padding: 10px 6px;
                  border-radius: 2px;
                  font-size: 12px;
                  transition: opacity 0.15s;
                  pointer-events: none;
                  white-space: nowrap;
                  display: block;
                  bottom: -50px;
                  right: -40px;
                  z-index: 7;
                  opacity: 0.8;
              }
              .voice {
                  height: 25px;
                  width: 25px;
              }
              .tooltip {
                  display: none;
              }
          }
      }
  }
  .right-section {
      display: flex;
      justify-content: space-between;
      width: 150px;
      margin-right: 30px;
      .upload-container {
          padding: 8px 8px;
          border-radius: 50%;
          border: none;
          display: flex;
          background-color: white;
          cursor: pointer;
          position: relative;
          transition: background-color 0.3s;
          &:hover {
              background-color:rgb(230, 230, 230);
          }
          &:hover .tooltip {
              font-family: sans-serif;
              position: absolute;
              background-color: grey;
              color: white;
              padding: 10px 6px;
              border-radius: 2px;
              font-size: 12px;
              transition: opacity 0.15s;
              pointer-events: none;
              white-space: nowrap;
              display: block;
              bottom: -50px;
              right: -5px;
              z-index: 7;
              opacity: 0.8;
          }
          .upload {
              height: 25px;
              width: 25px;
          }
          .tooltip {
              display: none;
          }
      }
      .notify {
          padding: 8px 8px;
          border-radius: 50%;
          border: none;
          display: flex;
          background-color: white;
          position: relative;
          cursor: pointer;
          transition: background-color 0.3s;
          &:hover {
              background-color:rgb(230, 230, 230);
          }
          &:hover .tooltip {
              font-family: sans-serif;
              position: absolute;
              background-color: grey;
              color: white;
              padding: 10px 6px;
              border-radius: 2px;
              font-size: 12px;
              transition: opacity 0.15s;
              pointer-events: none;
              white-space: nowrap;
              display: block;
              bottom: -50px;
              left: -15px;
              z-index: 7;
              opacity: 0.8;
          }
          .notify-icon {
              height: 25px;
              height: 25px;
          }
          .notify-count {
              background-color: red;
              color: white;
              padding: 5px 8px;
              border-radius: 50%;
              position: absolute;
              font-size: 12px;
              top: -2px;
              right: -1px;
          }
          .tooltip {
              display: none;
          }
      }
      .pin-girl {
          height: 40px;
          width: 40px;
          border-radius: 50%;
          margin-left: 10px;
          cursor: pointer;
        
      }
  }
}

解决步骤

问题核心是父容器没有弹性宽度约束,且输入框的固定width优先级高于flex属性,按以下修改SCSS:

1. 给.middle-section添加弹性宽度控制

.middle-section {
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
  // 新增以下代码
  flex: 1;
  max-width: 700px; // 搜索框最大宽度+搜索按钮宽度(600+50)
  min-width: 150px; // 搜索框最小宽度+搜索按钮宽度(100+50)
}

2. 让.search-bar占满父容器空间

.search-bar {
  display: flex;
  // 新增这一行
  flex: 1;
}

3. 修改.search-text的宽度属性

.search-text {
  flex-grow: 1;
  flex-shrink: 1;
  // 移除原有的width: 600px,替换为
  max-width: 600px;
  min-width: 100px;
  // 其他原有样式保留不变
}

4. 优化Header的间距(可选)

原gap:70px在小屏幕会导致布局拥挤,建议替换为弹性间距:

.header {
  // 替换gap:70px为
  gap: 1rem;
  // 调整padding,让左右间距一致
  padding: 0.5rem 0.5rem;
}

原理说明

  • .middle-section设置flex:1后,会占据Header中除左右固定宽度区域外的所有可用空间,同时通过max-width和min-width限制搜索区域的最大/最小宽度
  • .search-bar设置flex:1后,会完全填充.middle-section的可用宽度,确保搜索框能随父容器收缩
  • 输入框用max-width替代固定width,配合flex-grow和flex-shrink实现弹性伸缩,min-width保证缩小到一定程度后不再收缩

内容的提问来源于stack exchange,提问作者Hatter7474

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 14:42:32