这里的flex:1相当于flex: 1 1 0%,它是一个简写属性,表示项目(flex item)在弹性容器(flex container)中如何伸缩。它相当于flex: 1 1 0%,包含了三个子属性:

  • flex-grow 定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大。
  • flex-shrink 定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。
  • flex-basis 定义在分配多余空间之前,项目占据的主轴空间(main size),浏览器根据此属性计算主轴是否有多余空间,默认值为 auto ,即项目本身的大小。

二、flex:1

1. 语法定义

flex:1 是 flex-grow:1; flex-shrink:1; flex-basis:0% 的简写形式。

2. 核心行为

  • 空间分配逻辑:
    元素的初始尺寸由 flex-basis:0% 决定,即默认不占用任何空间。剩余空间会根据 flex-grow 的权重比例分配。例如,若两个元素均设置 flex:1,则平分剩余空间。

  • 收缩能力:
    当容器空间不足时,元素会按 flex-shrink:1 的比例收缩,但最小尺寸被限制为 0%(可能导致内容截断)。

3. 典型场景

  • 等分布局:多个子元素需均分容器宽度(如导航栏按钮)。
  • 内容无关的弹性区域:元素尺寸完全由容器剩余空间决定,忽略内容本身大小(如侧边栏和主内容区)。

二、flex:auto

1. 语法定义

flex:auto 等价于 flex-grow:1; flex-shrink:1; flex-basis:auto。

2. 核心行为

  • 空间分配逻辑:

元素的初始尺寸由 flex-basis:auto 决定(即元素本身内容或显式设置的宽度/高度)。剩余空间按 flex-grow 分配,但需叠加初始尺寸。例如,若元素 A 的 flex-basis 为 200px,元素 B 的 flex-basis 为 100px,剩余空间将按 200px:100px 的比例分配。

  • 收缩能力:

元素可收缩至小于初始尺寸(但不会小于 min-content),适合动态适配内容。

3. 典型场景

  • 内容优先的弹性布局:需根据内容动态调整(如卡片布局中部分卡片需固定宽度,另一部分自适应)。
  • 混合尺寸分配:需兼顾内容尺寸和剩余空间分配(如表单输入框与按钮组合)。

flex:1的作用

使用flex:1的作用是让项目能够自动填充剩余空间,实现自适应布局。例如,我们有一个水平排列的三个项目,它们的内容长度不一样,我们想让它们平均占据一行的空间,就可以给它们都设置flex:1。

在这里插入图片描述

flex:1 是 CSS 弹性盒布局中的一个常用属性简写,用于让子元素自动填充容器的剩余空间。

核心含义‌

  • flex:1 等同于 flex-grow:1、flex-shrink:1 和 flex-basis:0%
  • ‌flex-grow:1‌:当容器有剩余空间时,该项目会放大以填满空间
    ‌- flex-shrink:1‌:当空间不足时,该项目会按比例缩小
    ‌- flex-basis:0%`‌:在分配空间前,项目的基础尺寸为 0%

主要作用‌

‌‌- 自动分配空间‌:根据容器剩余空间自动调整项目大小
‌‌- 实现等高布局‌:即使内容不同,也能保证项目高度一致
‌- ‌响应式适配‌:轻松应对不同屏幕尺寸的布局需求

典型应用场景‌

.container {
  display: flex;
}
.sidebar {
  width: 200px;  /* 固定宽度 */
}
.main {
  flex: 1;       /* 自动填满剩余空间 */
}

#‌# 与 flex:auto 的区别‌

  • flex:1:空间不足时优先缩小自身尺寸
  • flex:auto:空间不足时优先保持内容完整显示

防止无限撑大的技巧‌

当 flex:1 的子项内容过多时,可设置 max-height 和 overflow:auto 来显示滚动条,而不是无限扩展。

实用建议‌:在构建侧边栏+内容区布局时,给固定宽高的侧边栏后,直接为主内容区设置 flex:1,即可实现完美的自适应填充效果。

import React from 'react';
import { View, Text, Dimensions, StyleSheet, Image, TextInput, AppRegistry } from 'react-native';
 
//获取屏幕的宽高
const screenWidth =Math.round( Dimensions.get('window').width);
const screenHight =Math.round( Dimensions.get('window').height);

const AppStyles = StyleSheet.create({
  wrap: {
    width: '100%',
    height: screenHight,
    backgroundColor: '#85BDFF'
  },
  title: {
    width: '100%',
    height: 72,
    fontFamily: 'OPPOSans, OPPOSans',
    fontWeight: 'normal',
    paddingTop: 50,
    fontSize: 36,
    color: '#304057',
    lineHeight: 72,
    textAlign: 'center',
    fontStyle: 'normal'
  },
  banner: {
    paddingTop: 50,
    paddingRight: 32,
    paddingLeft: 32,
  },
  bannerItem: {
    paddingTop: 10,
    display: 'flex',
    flexDirection:'row',
    alignItems: 'center',
    justifyContent: 'center',
    width: '50%',
  },
  loginBox: {
    width: '100%',
    paddingTop: 29,
    paddingLeft: 20,
    paddingRight: 20,
    borderTopRightRadius: 30,
    borderTopLeftRadius: 30,
    backgroundColor: '#F2F8FF',
    flex: 1
  }
})
function App() {
  return (
    <View style={AppStyles.wrap}>
      <Text style={AppStyles.title}>鸿蒙ReactNative系统</Text>
      <View style={AppStyles.banner}>
        <View style={{display:'flex',flexDirection:'row',justifyContent:'space-between'}}>
          <View style={AppStyles.bannerItem}>
            <Image style={{width:27,height:27}} source={require('./images/checked.png')}></Image>
            <Text style={{paddingLeft: 4}}>实时业绩便捷查询</Text>
          </View>
          <View style={AppStyles.bannerItem}>
            <Image style={{width:27,height:27}} source={require('./images/checked.png')}></Image>
            <Text style={{paddingLeft: 4}}>订单状态轻松把控</Text>
          </View>
        </View>
        <View style={{display:'flex',flexDirection:'row',justifyContent:'space-between'}}>
          <View style={AppStyles.bannerItem}>
            <Image style={{width:27,height:27}} source={require('./images/checked.png')}></Image>
            <Text style={{paddingLeft: 4}}>宣传数据全程管理</Text>
          </View>
          <View style={AppStyles.bannerItem}>
            <Image style={{width:27,height:27}} source={require('./images/checked.png')}></Image>
            <Text style={{paddingLeft: 4}}>海量素材一站转发</Text>
          </View>
        </View>
      </View>

      <Image style={{width:289, height: 182, display: 'flex', alignSelf: 'center', margin: 20}} source={require('./images/login-bg.png')}></Image>

      <View style={AppStyles.loginBox}>
        <TextInput style={{width: '100%', height: 48, borderRadius: 10, backgroundColor: '#FFFFFF', paddingLeft: 16, paddingRight: 16, fontSize: 14, color: '#304057'}}
         placeholder="请输入手机号"></TextInput>
      </View>
    </View>
  );
}
 
export default App;

在这里插入图片描述


解决了问题:

在Web开发初期,开发者主要依赖float、position和inline-block实现页面布局,垂直居中难题:传统方案需通过margin: auto、transform或绝对定位配合top:50%等hack实现,代码冗余且维护性差。

欢迎大家加入开源鸿蒙跨平台开发者社区,一起共建开源鸿蒙跨平台生态。

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐