解决弹性布局中子元素内容溢出问题

在移动端日常开发中经常会遇到这样一个场景,在一个列表中,左边是一张固定大小的图片,右边是一行或多行文字,宽度自适应,溢出省略,如下图

在这里插入图片描述
看到这个样式,略一思考,貌似用弹性布局就可以实现,左边固定宽度,右边设置flex:1。

html:

  <div class="list">
    <div v-for="(item, index) in list" :key="index" class="list-item">
      <img class="item-img" :src="item.imgs" />
      <div class="item-box">{{ item.title }}</div>
    </div>
  </div>

css:

    .list-item{
      width: 100%;
      height:80px;
      padding-left: 10px;
      padding-right: 10px;
      box-sizing: border-box;
      display:flex;
      align-items: center;
    }
    .item-img{
      width:36px;
      height:36px;
      margin-right: 10px;
    }
    .item-box{
      flex:1;
      overflow: hidden;
      white-space: nowrap;
      text-overflow: ellipsis;
    }

效果:
在这里插入图片描述
貌似成功了一半,右边一行内容的情况下已经实现了需要的效果。那么,右边是多行呢?

html:

  <div class="list">
    <div v-for="(item, index) in list" :key="index" class="list-item">
      <img class="item-img" :src="item.imgs" />
      <div class="item-box">
        <div class="item-title fn-text-overflow">{{ item.title }}</div>
        <div class="item-remark fn-text-overflow">{{ item.remark }}</div>
      </div>
    </div>
  </div>

css:

    .list-item{
      width: 100%;
      height:80px;
      padding-left: 10px;
      padding-right: 10px;
      box-sizing: border-box;
      display:flex;
      align-items: center;
    }
    .item-img{
      width:36px;
      height:36px;
      margin-right: 10px;
    }
    .item-box{
      flex:1;
    }
    .item-title{
      font-size:20px;
    }
    .item-remark{
      font-size:14px;
      color:#666;
    }
    .fn-text-overflow {
      overflow: hidden;
      white-space: nowrap;
      text-overflow: ellipsis;
    }

效果:
在这里插入图片描述
可以看到,当右边的 item-box 中包含其他的子元素时,即使设置了 flex:1,子元素的宽度仍然超出了屏幕,需要在 item-box 上也加上 fn-text-overflow 才能实现省略效果。
html:

  <div class="list">
    <div v-for="(item, index) in list" :key="index" class="list-item">
      <img class="item-img" :src="item.imgs" />
      <div class="item-box fn-text-overflow">
        <div class="item-title fn-text-overflow">{{ item.title }}</div>
        <div class="item-remark fn-text-overflow">{{ item.remark }}</div>
      </div>
    </div>
  </div>

效果:
在这里插入图片描述
大功告成!

另外,当时在写这个的时候想到了另一种思路,既然 item-box 中不能包含子元素,那把其中的 div 去掉,只展示内容不就可以了?就像下面这样:

html:

  <div class="list">
    <div v-for="(item, index) in list" :key="index" class="list-item">
      <img class="item-img" :src="item.imgs" />
      <div class="item-box fn-text-overflow">
        {{ item.title }} <br> {{ item.remark }}
      </div>
    </div>
  </div>

效果:
在这里插入图片描述
新的问题又来了,怎么给右边的两行文字加上不同的样式?
这时候我发现了 display: contents 这个属性。先来看看它的作用吧。

元素本身不产生任何边界框,而元素的子元素与伪元素仍然生成边界框,元素文字照常显示。为了同时照顾边界框与布局,处理这个元素时,要想象这个元素不在元素树型结构里,而只有内容留下。这包括元素在元文档中的子元素与伪元素,比如::before和::after这两个伪元素,如平常一样,前者仍然在元素子元素之前生成,后者在之后生成。

简而言之就是将元素的边界框去掉,元素的背景、边框和填充部分都不会渲染,只渲染元素中的内容,而和内容相关的 color 、font 也能正常生效。

html:

  <div class="list">
    <div v-for="(item, index) in list" :key="index" class="list-item">
      <img class="item-img" :src="item.imgs" />
      <div class="item-box fn-text-overflow">
        <div class="item-title">{{ item.title }}</div>
        <br>
        <div class="item-remark">{{ item.remark }}</div>
      </div>
    </div>
  </div>

css:

    .list-item{
      width: 100%;
      height:80px;
      padding-left: 10px;
      padding-right: 10px;
      box-sizing: border-box;
      display:flex;
      align-items: center;
    }
    .item-img{
      width:36px;
      height:36px;
      margin-right: 10px;
    }
    .item-box{
      flex:1;
    }
    .item-title{
      font-size:20px;
    }
    .item-remark{
      font-size:14px;
      color:#666;
    }
    .item-title,.item-remark{
      display: contents;
    }
    .fn-text-overflow {
      overflow: hidden;
      white-space: nowrap;
      text-overflow: ellipsis;
    }

效果:
在这里插入图片描述
不过使用这个属性要注意各个浏览器的兼容性问题,比如万恶的IE就不支持这个属性。。。
在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值