uniapp下页面布局分析二——固定部分元素到底部

接上篇内容。继续添加内容。

以下方案建立在App.vue设置了flex布局。

在底部添加一个固定的栏目

<template>
    <view style="flex: auto; background-color: red">
        <view style="bottom: 0">我固定在底部</view>
    </view>
</template>

我试着向上面这样添加一个底部工具栏,但是发现不行bottom: 0无法生效。

于是我想到用position: absolute做绝对定位:

<template>
    <view style="flex: auto; background-color: red">
        <view style="position: absolute; bottom: 0px">我固定在底部</view>
    </view>
</template>

这样就可以了,因为position: absolute;是在父元素的束缚下进行绝对定位的,这样就是我想要的效果。
那我继续添加一些内容,看看会不会影响到它:

<template>
    <view style="flex: auto; background-color: red">
        <view>干扰一</view>
        <view style="position: absolute; bottom: 0px">我固定在底部</view>
        <view>干扰二</view>
    </view>
</template>

可以发现,不管我在它上面还是下面添加元素,都不影响它:
在这里插入图片描述
继续加大难度,给元素增加高度满屏高度,看看会不会挤压它:

<template>
    <view style="flex: auto; background-color: red">
        <view style="height: 100%">干扰一</view>
        <view style="position: absolute; bottom: 0px">我固定在底部</view>
        <view>干扰二</view>
    </view>
</template>

在这里插入图片描述
可以发现,底部元素纹丝不动,但是“干扰二”不见了,调试发现:
在这里插入图片描述
它被挤到下面去了,但是因为底部导航栏是顶层元素,所以将他覆盖了。这也正常。目前测试功能很好。absolute的解析看这篇

也可以像下面的顺序放置,效果也一样(变化了一下父级关系):

<template>
    <view style="flex: auto; background-color: red">干扰一</view>
    <view style="position: absolute; bottom: 0px">我固定在底部</view>
</template>

另一种底部固定方案

上面方案是使用absolute,效果很好。我发现还有一种方案,也记录一下:

<template>
    <view style="flex: auto; background-color: red">干扰一</view>
    <view style="bottom: 0px">我固定在底部</view>
</template>

与上面的不同是去掉了position: absolute;
在这里插入图片描述
发现,一样可以让其固定在底部,但是它的底色就不是红色了。这时候就体现出absolute的层次效果了。因为absolute会让它“隐身”,上面的元素感知不到它的存在,所以红色理所应当的把全屏占掉了。但是不用的话,两组元素是并存的关系。所以底部元素占用的位置不会被红色侵占。

这种方式依赖“flex: auto; ”,这会让元素占满父元素剩余空间。

我给它添加一些干扰,看看是否会影响底部元素的位置:

<template>
    <view style="flex: auto; background-color: red; height: 200px">干扰一</view>
    <view style="bottom: 0px; height: 50px">我固定在底部</view>
</template>

它的效果图如下:
在这里插入图片描述

可以看到,我给上面的元素设置的高度超过了它可占用的空间,然后底部元素和它都被一定程度压缩了。

这是因为flex布局的默认值是:当父元素空间小于子元素空间之和时(空间指的长度或者宽度),会进行等比缩小。所以只需要设置底部元素不缩小即可。这个flex的默认值是0 1 auto。第一个值表示放大的比例,第二个表示缩小的比例,都设置为0就不放大也不缩小了。auto就去看这篇解析吧,所以只需要设置成flex:0 0 auto。这样就不受影响了:

<template>
    <view style="flex: auto; background-color: red; height: 200px">干扰一</view>
    <view style="flex: none; bottom: 0px; height: 50px">我固定在底部</view>
</template>

这里面:flex: auto等于flex:1 1 autoflex: none;等于flex: 0 0 auto

所以这种方案也是可行的。

但是,这种方案并不稳定,如果上面的元素包含的子元素高度大于了其本身,就会改变它的高度。导致底部元素被压缩:

<template>
    <view style="flex: auto; background-color: red; height: 200px">
        <view style="height: 180px; background-color: blue"> 干扰一 </view>
    </view>
    <view style="flex: none; bottom: 0px; height: 50px">我固定在底部</view>
</template>

因为“干扰一” 的布局是display: block;。这么看来,这种方案不如第一个稳定。还是会被其他布局的元素给影响。
在这里插入图片描述
当然也有解决方案,给上面的元素添加overflow属性。可以选择将超出部分被裁减,也可以变成滚动区域,但是,它需要父元素指定高度。

下面这种方式不行(最外层view的父元素是flex布局,且指定了height: 100%;),即使使用flex: auto;占满高度也是不行的。子元素超过父元素高度会导致滚动贯穿。

<template>
    <view style="flex: auto; display: flex; flex-direction: column">
        <view style="flex: auto; background-color: red; height: 200px; overflow: auto">
            <view style="height: 180px; background-color: blue"> 干扰一 </view>
        </view>
        <view style="flex: none; bottom: 0px; height: 50px">我固定在底部</view>
    </view>
</template>

需要在父元素指定高度:

<template>
    <view style="height: 100%; display: flex; flex-direction: column">
        <view style="flex: auto; background-color: red; height: 200px; overflow: auto">
            <view style="height: 180px; background-color: blue"> 干扰一 </view>
        </view>
        <view style="flex: none; bottom: 0px; height: 50px">我固定在底部</view>
    </view>
</template>

对比上面就把flex: auto换成height: 100%,可以使用相对高度,所以也能接受。

对比

第一种方案,它的特点是上面的元素始终占满整个可用空间,包括底部元素的空间,只是底部元素位于它的上面一层,所以不会被其遮挡,对于上面的元素而言,它是感知不到底部元素的存在的。

第二种方案,上面的元素和底部元素是并存的,是可以相互感知到彼此的存在。这样,上面的元素是能够获取到自己真实的高度。当然,底部元素也依赖于上面元素占用剩余空间,才会把自己的位置定死在底部。就稳定性而言,第一种更好。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lsjweiyi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值