英文:
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 -->
<div class="wrapper">
<div id="portalContainer">
<button>Button 1</button>
</div>
<button>Button 2</button>
</div>
<!-- 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 -->
<div class="wrapper">
<div id="portalContainer"></div>
<button>Button 2</button>
</div>
<!-- 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 -->
<div class="wrapper">
<div id="portalContainer"></div>
<button>Button 2</button>
</div>
<!-- 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.
<script>
document.querySelectorAll("#portalContainer").forEach((element) => { if (!element.hasChildNodes()) element.style.display = "none" })
</script>
Keep in mind that id's must be unique in html!
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论