引言
在业务开发中经常会遇到下面这种布局,元素下外边距10px此类。
而为了保持父级盒子的效果,往往会要求最后一行的下边距为0,常规的做法是用css选择器来设置。
&:nth-last-child(-n + 3) {
margin-bottom: 0;
}
场景
而上面的业务场景是定宽的盒模型,也就是每个子元素宽度固定,换而言之每行的子元素数量固定,所以我们可以用css选择器达到这种效果。
本文我们将要讨论的是自适应宽度的场景,如下
可以看到的是,每个子元素的宽度根据内容自适应,上面的方案行不通,我们需要一种新的方法来实现。
方案1
第一种方案css实现
实现思路就是用父元素的margin去抵消子元素margin
不过可以看到的是会导致盒模型定位很奇怪,与顶部蓝色块重合了,对于后期维护可能会带来一定困扰。
方案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即可,实现效果如下图
结语
相应的,此方案延伸出去还可以实现其它不同的边距处理等等