当元素宽度大于父元素宽度时,元素之间的CSS动态间距

gr8qqesn  于 2023-05-02  发布在  其他
关注(0)|答案(1)|浏览(132)

我有一个问题,我已经解决了与Javascript,不认为是可能的只是CSS,但认为我会问,因为所有CSS解决方案将更干净。
给定以下HTML:

<div class="items">
    <a class="item">Some Text</a>
    <a class="item">different Text</a>
    ...
  </div>

Div items具有动态宽度(width: 100%),每个item将出现在一行中;从左到右,不对齐。每个项目的width由文本(即width未设置),并且项目的确切数量未知(在5到8之间)。
每个项目之间的空间最大为32 px,最小为8 px,如果这不会导致item s超过items div的宽度,则它们为32 px,如果item s的宽度超过items div,则每个项目之间的空间将动态收缩,以保持item s的宽度小于其父级,最小为8 px之后items将溢出。
示例:x1c 0d1x
做这样的事情很容易:

.items {
  width: 100%;
  display: flex;
}

.item {
  margin-right: 32px

  &:last-child { // Cheating and using SCSS syntax but you get the idea
    margin-right: 0;
  }
}

items div足够大以容纳所有内容时,这是可行的,但我不知道如何使用任何方法(使用margin,spacer div,flex-gap)来实现动态间距。我可以用@media查询来欺骗它,但是我仍然硬编码这些限制,并且它不是基于项目的动态的。由于项目的数量是未知的,它们的宽度没有设置,我猜这是不可能的,没有Javascript。
我最终的JavaScript解决方案是这样的:

const ro = new ResizeObserver(entries => {
  for (let entry of entries) {
   const items = entry.target
   const itemsWidth = items.clientWidth;
   const children = items.getElementsByClassName('item');

   let itemCount = 0; // Number of Children
   let itemTotalLengths = 0; // Combined length of children
   for (item of children) {
       itemCount += 1;
       itemTotalLengths += item.clientWidth; //Assumes no border
   }
   
   let margin = (itemsWidth - itemTotalLengths)/(itemCount - 1) // Assume itemCount at least 2
   margin = Math.min(32, margin);
   margin = Math.max(8, margin);

   console.log(`setting margin to ${margin}`);
   for (i = 0; i < children.length -1; ++i) {
       const item = children[i];
       item.style.marginRight = `${margin}px`;
   }   
  }
});

// On resize of items
ro.observe(document.getElementsByClassName('items'));

这是可行的,但如果可能的话,CSS解决方案将是首选。任何一点领悟都是超级有用的!

3okqufwl

3okqufwl1#

间隔元件应该工作正常,使用flex-growflex-shrink可以执行以下操作:

.items {
  display: flex;
  overflow: scroll;
  width: 100%;
}

.item {
  flex: 0 0 auto;
}

.spacer {
  flex: 1 1 8px;
  min-width: 8px;
  max-width: 32px;
}
<div class="items">
  <div class="item">Info</div>
  <div class="spacer"></div>
  <div class="item">Overview</div>
  <div class="spacer"></div>
  <div class="item">Notes</div>
  <div class="spacer"></div>
  <div class="item">Emails</div>
</div>

(Try调整窗口宽度以查看它的发生)

相关问题