flexbox 是不是可以通过文本换行捕捉到网格?

Posted

技术标签:

【中文标题】flexbox 是不是可以通过文本换行捕捉到网格?【英文标题】:Is flexbox snapping to grid with text wrapping possible?flexbox 是否可以通过文本换行捕捉到网格? 【发布时间】:2019-10-22 08:57:19 【问题描述】:

所以我喜欢这个,它可以包裹,但盒子两边都对齐并填满了整个空间。

<head>
<style>
* 
  padding: 0px;
  margin: 0px;
  text-transform: none;
  font-style: normal;


p 
  display: flex;
  flex-wrap: wrap;
  width: 200px;


i 
  flex: 1;
  padding: 5px;
  margin: 2px;
  background: #ddd;
  text-align: center;

</style>
</head>
<body>
  <p>
    <i>foo</i><i>hello</i><i>congratulations</i><i>forward</i><i>interesting</i><i>place</i><i>walk</i><i>to</i><i>anyplace</i><i>next</i><i>sophisticationism</i>
  </p>
</body>

混合使用大小词,它以某种方式找出如何以最佳方式布置它们,从而完全填满空间。

我现在想做的是,不是让每个框都是动态宽度的矩形,而是让框“对齐网格”可以这么说。也就是说,想象一下每一行都有一个正方形网格。有点像这样(我已经完全硬编码,只是为了展示它的外观。实际上这就是我的问题,如何使用 FlexBox 使其自动化)。

<head>
<style>
* 
  padding: 0px;
  margin: 0px;
  text-transform: none;
  font-style: normal;


p 
  display: flex;
  flex-wrap: wrap;
  width: 220px;


i 
  width: 50px;
  height: 50px;
  padding: 5px;
  margin: 2px;
  background: #ddd;
  text-align: center;


.l 
  width: 114px;

</style>
</head>
<body>
  <p>
    <i>a</i><i>a</i><i>a</i><i>a</i><i class='l'>long</i><i>a</i><i class='l'>long</i><i>a</i><i class='l'>a</i><i class='l'>long</i><i>a</i><i>a</i><i>a</i><i>a</i><i>a</i><i>a</i><i>a</i>
  </p>
</body>

所以换个说法,我的问题是如何使 流动 文本(如上图中的单词)布局,以便 (a) 它填充每一行,并且 (b) 每个框都是倍数的一个正方形。也就是说,它捕捉到一个正方形的网格,天气它是 1、2、3+ 个正方形,而不是 2.5 个正方形或 1.2345 个正方形或其他东西。它总是捕捉到整个块。它首先查看 longer 词,然后计算它将占用多少块。然后它会拉伸任何较短的块(如上例中的一个字母“a”)以填充空白。

想知道如何使用 FlexBox 或 CSS 来实现。

【问题讨论】:

无法使用 CSS flexbox 或 css-grid。 我更新答案 【参考方案1】:

尝试(我使用拆分 1-3 个单词取决于来自 here 的长度)

function show(n) 
  text.innerhtml = '<p>' + split(text.innerText,n).map(line=> 
    if(line.length==2 && line[0].length<n && line[1].length<n) 
      // case for two short words
      return `<i class='long'>$line[0]</i><i class='short'>$line[1]</i>`
     else 
      return line.map(w=>`<i class='$w.length<9 ?'short':'long''>$w</i>`).join('')
    
  ).join('') + '</p>';



function split(str,n) 
  let z=0, b=[], r=[], w=str.split(' ');
  let s = w.map(v => v.length < n ? 1 : 2);

  s.map((v,i)=>( 
    z+v>=4 ? (r.push(b),z=0,b=[]) : 0,
    z+=v, b.push(w[i]) 
  ))

  return b.length ? r.concat([b]) : r;



show(9) // 9 is min number of letters for long words;
.short 
  flex-basis: 64px;
  flex-grow: 1


.long 
  flex-basis: 140px;
  flex-grow: 2


* 
  padding: 0px;
  margin: 0px;
  text-transform: none;
  font-style: normal;


p 
  display: flex;
  flex-wrap: wrap;
  width: 260px;


i 
  flex: 1;
  padding: 5px;
  margin: 2px;
  background: #ddd;
  text-align: center;
&lt;div id="text"&gt;a aaa foo hello congratulations forward interesting place walk to anyplace next sophisticationism aa bb cccccccccc ddd&lt;/div&gt;

【讨论】:

这仅适用于等宽字体。我希望它适用于任何 unicode 字符和字体。

以上是关于flexbox 是不是可以通过文本换行捕捉到网格?的主要内容,如果未能解决你的问题,请参考以下文章

Flexbox项目换行到新行[重复]

由于填充,Flexbox 无法使文本居中

Flexbox 网格 - 对齐:围绕空格并对齐最后一个项目

Flexbox 挑战:如何在整行中使用相同且均匀的边距进行换行

带边距排水沟的 Flexbox 网格系统

Safari flexbox 文本换行问题