如何使一个 flexbox 容器适用于多个元素,但只有一个可见。

huangapple go评论69阅读模式
英文:

How to make a flexbox container work for multiple elements, but only one is visible

问题

由于我的HTML设置方式,其中一个按钮被包裹在一个<div>中。这个<div>会始终被渲染,即使它内部没有内容(即没有按钮)。这是因为这个<div>是一个React portal的目标。

在我不希望渲染“Button 1”的情况下,我仍然需要包装的portalContainer存在。我无法绕过这个问题。

问题出在portalContainer没有内容(没有按钮被渲染到其中),但是“Button 2”却被渲染到了一侧。这是因为flexbox仍然尝试均匀地分配元素,即使其中一个元素内部没有内容。示例:

<div class="wrapper">
  <div id="portalContainer"></div>
  <button>Button 2</button>
</div>

如何使“Button 2”的单个实例显示在容器的中间,即使portalContainer仍然存在于DOM中?

我研究了将portalContainer设置为display: none;,然后在容器内有按钮时使用类似于:has(button)的方式取消该样式。然而,:has()在Firefox中不被支持。

有没有办法做到这一点?我不能对portalContainer的渲染应用任何逻辑 - 它必须始终存在。

英文:

I have a container which can contain several buttons (feasibly up to 3).

I have used flexbox to make my desired layout. In this layout, all buttons are rendered in a line and space-evenly is used to give space between each item. E.g:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-css -->

.wrapper {
  display: flex;
  justify-content: space-evenly;
  
  width: 500px;
  background-color: grey;
}

button {
  height: 75px;
}

<!-- language: lang-html -->

&lt;div class=&quot;wrapper&quot;&gt;
  &lt;div id=&quot;portalContainer&quot;&gt;
    &lt;button&gt;Button 1&lt;/button&gt;
  &lt;/div&gt;
  &lt;button&gt;Button 2&lt;/button&gt;
&lt;/div&gt;

<!-- end snippet -->

Due to how my HTML is set up, one of the buttons is wrapped in a div. This div is always rendered even when it does not have content (a button) to go inside it. The reason for this is because this div is the target for a React portal.

In a situation where I do not wish to render Button 1 I still require the wrapping div portalContainer to exist. I cannot get around this.

The issue therefore arises where the portalContainer has no content (no button was rendered into it) but Button 2 renders off to the side. This is due to flexbox still attempting to space the elements evenly, even when one element has nothing inside it. Example:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-css -->

.wrapper {
  display: flex;
  justify-content: space-evenly;
  
  width: 500px;
  background-color: grey;
}

button {
  height: 75px;
}

<!-- language: lang-html -->

&lt;div class=&quot;wrapper&quot;&gt;
  &lt;div id=&quot;portalContainer&quot;&gt;&lt;/div&gt;
  &lt;button&gt;Button 2&lt;/button&gt;
&lt;/div&gt;

<!-- end snippet -->

How can I make the solo instance of Button 2 show in the centre of the wrapper, even though portalContainer is still in the DOM?

I looked into the possibility of setting portalContainer as display: none; and then using something like :has(button) to unset that style when the container has a button inside. However :has() does not have Firefox support.

Is there a way of doing this? I cannot apply any logic to rendering the portalContainer - it must always be there.

Full example here in Codepen: https://codepen.io/asos-francesca/pen/qBQKPOX

答案1

得分: 3

你可以使用:empty伪选择器,它具有更广泛的浏览器支持:

https://caniuse.com/?search=%3Aempty

.wrapper {
  display: flex;
  justify-content: space-evenly;
  width: 500px;
  background-color: grey;
}

button {
  height: 75px;
}

#portalContainer:empty {
  display: none;
}
<div class="wrapper">
  <div id="portalContainer"></div>
  <button>Button 2</button>
</div>
英文:

You can use the :empty pseudo-selector instead, which has greater browser support:

https://caniuse.com/?search=%3Aempty

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-css -->

.wrapper {
  display: flex;
  justify-content: space-evenly;
  width: 500px;
  background-color: grey;
}

button {
  height: 75px;
}

#portalContainer:empty {
  display: none;
}

<!-- language: lang-html -->

&lt;div class=&quot;wrapper&quot;&gt;
  &lt;div id=&quot;portalContainer&quot;&gt;&lt;/div&gt;
  &lt;button&gt;Button 2&lt;/button&gt;
&lt;/div&gt;

<!-- end snippet -->

答案2

得分: 0

你可以使用JavaScript仅在容器没有任何子元素的情况下将display:none设置为portalContainer。下面的代码段在CodePen上解决了这个问题。

<script>
  document.querySelectorAll("#portalContainer").forEach((element) => { if (!element.hasChildNodes()) element.style.display = "none" })
</script>

请记住,在HTML中,id必须是唯一的!

英文:

You can use Javascript to set the display:none to portalContainer only if the conainer doesn't have any childrens.
The next code snippet resolved the problem on CodePen.

&lt;script&gt;
  document.querySelectorAll(&quot;#portalContainer&quot;).forEach((element) =&gt; { if (!element.hasChildNodes()) element.style.display = &quot;none&quot; })
&lt;/script&gt;

Keep in mind that id's must be unique in html!

huangapple
  • 本文由 发表于 2023年7月20日 19:40:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/76729466.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定