css最后一行间距控制方案

1,384 阅读2分钟

引言

在业务开发中经常会遇到下面这种布局,元素下外边距10px此类。

image.png

而为了保持父级盒子的效果,往往会要求最后一行的下边距为0,常规的做法是用css选择器来设置。

&:nth-last-child(-n + 3) {
  margin-bottom: 0;
}

场景

而上面的业务场景是定宽的盒模型,也就是每个子元素宽度固定,换而言之每行的子元素数量固定,所以我们可以用css选择器达到这种效果。

本文我们将要讨论的是自适应宽度的场景,如下 image.png

可以看到的是,每个子元素的宽度根据内容自适应,上面的方案行不通,我们需要一种新的方法来实现。

方案1

第一种方案css实现

image.png

实现思路就是用父元素的margin去抵消子元素margin

image.png 不过可以看到的是会导致盒模型定位很奇怪,与顶部蓝色块重合了,对于后期维护可能会带来一定困扰。

方案2

既然css不是很好用,那么就得上js了

const Test = () => {
  let ref = useRef<HTMLDivElement>(null);

  // tag有下边距,使用js计算,如果不是最后一行给值
  useEffect(() => {
    let p_el = ref.current;
    let p_scroll_top = p_el?.clientHeight!;
    ref.current?.querySelectorAll('.comp_tab_tag_content')!.forEach((item: any) => {
      if (p_scroll_top > item.offsetHeight + item.offsetTop) {
        item.style.marginBottom = '6px';
      }
    });
  }, []);

  return (
    <>
      <div className={styles.bg}></div>
      <div className={styles.list} ref={ref}>
        {['发烧', '分公司', '3', '4甘肃省', '合适的版本', '经济结构高度', '232', '怪怪的', '本地'].map((i) => (
          <div key={i} className={styles.part + ' comp_tab_tag_content'}>
            {i}
          </div>
        ))}
      </div>
    </>
  );
};

// less-module
.bg {
  background-color: deepskyblue;
  height: 40px;
}
.list {
  display: flex;
  justify-content: flex-start;
  flex-wrap: wrap;
  position: relative;
  .part {
    flex-shrink: 0;
    padding: 4px 8px;
    border-radius: 4px;
    background-color: chocolate;
    color: #fff;
    margin: 0 10px 0 0;
  }
}

实现思路是通过js元素选择器获取每个子元素与父元素的相对位置,从而得出元素是否为最后一行,然后给予不同子元素不同的margin即可,实现效果如下图

image.png

结语

相应的,此方案延伸出去还可以实现其它不同的边距处理等等

引申

image.png