英文:
Truncate text inside Twitter Bootstrap v5 Navbar
问题
如何在 Bootstrap 导航栏的 nav-link 或 nav-text 中截断动态文本(具有可变宽度)?
附注:使用显式宽度时,此代码正常工作,例如:<a class="nav-link disabled text-truncate" style="max-width: 150px;">
,但宽度未知。
期望的行为是在桌面和移动视口上截断文本,无论视口大小如何。
英文:
How to truncate dynamic text(with variable width) inside a nav-link or nav-text in a bootstrap navbar?
P.S.: With explicit width, this code just works fine, ex.: <a class="nav-link disabled text-truncate" style="max-width: 150px;">
but the width is unknown.
The expected behavior, is truncate text on desktop and mobile viewports, no matter which viewport size.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-html -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
<nav class="navbar navbar-expand-lg bg-body-tertiary">
<div class="container-fluid">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
Dropdown
</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#">Action</a></li>
<li><a class="dropdown-item" href="#">Another action</a></li>
<li>
<hr class="dropdown-divider">
</li>
<li><a class="dropdown-item" href="#">Something else here</a></li>
</ul>
</li>
<li class="nav-item">
<a class="nav-link disabled text-truncate">long long long long long long long long long long long long long long long long long long long long long long long long long long long text</a>
</li>
</ul>
<div class="d-flex" role="search">
<input class="form-control me-2" type="search" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success" type="submit">Search</button>
</div>
</div>
</div>
</nav>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>
<!-- end snippet -->
I've tried @isherwood suggestions, but without success:
First:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-css -->
.flex-parent,
.flex-parent-parent,
.flex-parent-parent-parent {
display: flex;
padding: 10px;
border: solid;
min-width: 100px;
}
.flex-parent {
min-width: 0;
}
.long-and-truncated {
flex: 1;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
<!-- language: lang-html -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
<nav class="navbar navbar-expand-lg bg-body-tertiary">
<div class="container-fluid">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
Dropdown
</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#">Action</a></li>
<li><a class="dropdown-item" href="#">Another action</a></li>
<li>
<hr class="dropdown-divider">
</li>
<li><a class="dropdown-item" href="#">Something else here</a></li>
</ul>
</li>
<li class="nav-item">
<div class="flex-parent-parent-parent">
<div class="flex-parent-parent">
<div class="flex-parent">
<div class="flex-child long-and-truncated">
1. This is a loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong string that is OK to truncate please and thank you
</div>
</div>
</div>
</div>
</li>
</ul>
<div class="d-flex" role="search">
<button class="btn btn-outline-success">Search</button>
</div>
</div>
</div>
</nav>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>
<!-- end snippet -->
Second:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-css -->
.wrapper {
display: flex;
/* width: 200px; */
align-content: stretch;
padding: 5px;
min-width: 0;
border: 1px solid
}
.wrapper .child2 {
flex-grow: 1;
overflow: hidden;
}
.flex {
display: flex;
min-width: 0;
}
.el {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.child1 {
background: red;
}
.child2 {
background: lightblue;
}
.child3 {
background: green;
}
.wrapper>* {
padding: 5px;
}
<!-- language: lang-html -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" />
<nav class="navbar navbar-expand-lg bg-body-tertiary">
<div class="container-fluid">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
Dropdown
</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#">Action</a></li>
<li><a class="dropdown-item" href="#">Another action</a></li>
<li>
<hr class="dropdown-divider">
</li>
<li><a class="dropdown-item" href="#">Something else here</a></li>
</ul>
</li>
<li class="nav-item">
<div class="wrapper">
<div class="child1">child1</div>
<div class="child2">
<div class="flex">
<div class="el">long long long long long long long long long long long long long long long long long long long long text</div>
<div>a</div>
</div>
</div>
<div class="child3">child3</div>
</div>
</li>
</ul>
<div class="d-flex" role="search">
<button class="btn btn-outline-success">Search</button>
</div>
</div>
</div>
</nav>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js"></script>
<!-- end snippet -->
Both(apparently) need a explicit width to truncate text.
My text come from API, and have no length restriction, that cause in a layout mess.
答案1
得分: 1
将网格添加到包装类将起作用。
.wrapper {
display: grid;
align-content: stretch;
padding: 5px;
min-width: 0;
border: 1px solid;
}
英文:
Adding grid to wrapper class will work
.wrapper{
display: grid;
align-content: stretch;
padding: 5px;
min-width: 0;
border: 1px solid
}
</details>
# 答案2
**得分**: 0
这是你的解决方案,
注释的 CSS 在底部是我第一次尝试实现结果的,更简洁,但由于 Bootstrap 在较小设备上使用 flex-wrap 而不是更改 flex 方向,`overflow-x:hidden` 阻止了下拉导航项显示,所以注释的 CSS 防止了下拉导航栏项显示其内容。
然后,我通过对 CSS 行为进行一些调整,为我知道会溢出的项目指定了一些小宽度,并添加了一些媒体查询规则,解决方案运行良好,检查一下。
最后,我使溢出的文本在悬停时可滚动,同时隐藏其滚动条,因此可以通过滚动查看截断的文本,而不是完全无法访问。
``` js hide: false console: true babel: false --
<!-- language: lang-css -->
.container-fluid-custom{
width: 100vw;
}
.navbar-nav-custom {
flex: 1;
width: 0;
}
.nav-item-custom::-webkit-scrollbar {
display: none;
}
.nav-item-custom {
flex: 1;
width: 0;
}
.nav-item-custom:hover{
margin-right: 1rem;
overflow: auto;
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */
}
.nav-item-custom:hover .text-truncate{
overflow: visible !important;
}
@media (max-width: 992px) {
.show {
width: 100%;
}
.navbar-nav {
width: 100%;
overflow-x: hidden;
}
.nav-item-custom {
width: 100%;
}
}
<!-- language: lang-html -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
<nav class="navbar navbar-expand-lg bg-body-tertiary">
<div class="container-fluid container-fluid-custom">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse navbar-collapse-custom" id="navbarSupportedContent">
<ul class="navbar-nav navbar-nav-custom me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
Dropdown
</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#">Action</a></li>
<li><a class="dropdown-item" href="#">Another action</a></li>
<li>
<hr class="dropdown-divider">
</li>
<li><a class="dropdown-item" href="#">Something else here</a></li>
</ul>
</li>
<li class="nav-item nav-item-custom">
<a class="nav-link disabled text-truncate">long long long long long long long long long long long long long long long long long long long long long long long long long long long text</a>
</li>
</ul>
<div class="d-flex" role="search">
<input class="form-control me-2" type="search" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success" type="submit">Search</button>
</div>
</div>
</div>
</nav>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>
<!-- end snippet -->
commented CSS of first trial, where dropdown item got hidden by `overflow-x: hidden`. This isn't the solution, but for reference, if you want to try it and maybe come out with another solution.
/* .navbar-collapse-custom{
overflow-x: hidden;
}
.navbar-nav-custom{
white-space: nowrap;
overflow-x: hidden;
text-overflow: ellipsis;
}
.nav-item-custom{
overflow-x:hidden;
*/
<details>
<summary>英文:</summary>
Here's your solution,
Notes:
* The commented css at the bottom was my first attempt to achieve the result and was more concise it achieved it, but as bootstrap uses flex-wrap on smaller devices rather than changing flex direction, the `overflow-x:hidden` prevented the dropdown to show, so commented css prevent dropdown navbar item from showing its content.
* Then I modified the solution by coming with some tweaks for the css behavior by specifying some small widths for items that I know would overflow and adding some media query rules and the solution is working fine, check it.
* Finally, I made the text that overflows scrollabe when hovering over it while hiding its scrollbars, so truncated text can be scrolled through and seen entirely rather than being totally inaccessible.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-css -->
.container-fluid-custom{
width: 100vw;
}
.navbar-nav-custom {
flex: 1;
width: 0;
}
.nav-item-custom::-webkit-scrollbar {
display: none;
}
.nav-item-custom {
flex: 1;
width: 0;
}
.nav-item-custom:hover{
margin-right: 1rem;
overflow: auto;
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */
}
.nav-item-custom:hover .text-truncate{
overflow: visible !important;
}
@media (max-width: 992px) {
.show {
width: 100%;
}
.navbar-nav {
width: 100%;
overflow-x: hidden;
}
.nav-item-custom {
width: 100%;
}
}
<!-- language: lang-html -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
<nav class="navbar navbar-expand-lg bg-body-tertiary">
<div class="container-fluid container-fluid-custom">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse navbar-collapse-custom" id="navbarSupportedContent">
<ul class="navbar-nav navbar-nav-custom me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
Dropdown
</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#">Action</a></li>
<li><a class="dropdown-item" href="#">Another action</a></li>
<li>
<hr class="dropdown-divider">
</li>
<li><a class="dropdown-item" href="#">Something else here</a></li>
</ul>
</li>
<li class="nav-item nav-item-custom">
<a class="nav-link disabled text-truncate">long long long long long long long long long long long long long long long long long long long long long long long long long long long text</a>
</li>
</ul>
<div class="d-flex" role="search">
<input class="form-control me-2" type="search" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success" type="submit">Search</button>
</div>
</div>
</div>
</nav>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>
<!-- end snippet -->
commented CSS of first trial, where dropdown item got hidden by `overflow-x: hidden`. This isn't the solution, but for reference, if you want to try it and maybe come out with another solution.
/* .navbar-collapse-custom{
overflow-x: hidden;
}
.navbar-nav-custom{
white-space: nowrap;
overflow-x: hidden;
text-overflow: ellipsis;
}
.nav-item-custom{
overflow-x:hidden;
} */
**An advice:**
* with your progression on front end development, you would see custom made libraries such as bootstrap hinders your freedom of implementation, that's why in some cases you should create your own UI components from scratch fully customized to your own purpose.
</details>
# 答案3
**得分**: 0
我不太明白你实际的问题,说实话,你一直通过添加更多嵌套元素或更多 flex 元素来改变问题范围。这里是你**第一**和**第二**个例子的修复。
```css
.expect-long {
min-width: 0;
}
.expect-long *:has(.long) {
min-width: 0;
display: flex;
}
.long {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.nav-item:has(.long) {
display: flex;
align-items: center;
}
.wrapper {
display: flex;
}
.wrapper > * {
padding: 5px 15px;
}
.child1 {
background: red;
}
.child2 {
background: lightblue;
}
.child3 {
background: green;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" />
<nav class="navbar navbar-expand-lg bg-body-tertiary">
<div class="container-fluid">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse expect-long" id="navbarSupportedContent">
<!-- ... (其余 HTML 代码) ... -->
</div>
</div>
</nav>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js"></script>
英文:
I don't get your actual problem to be honest, you keep changing the problem scope by adding more nested elements or more flex elements. Here is a fix for your First and Second examples.
<!-- begin snippet: js hide: false console: true babel: null -->
<!-- language: lang-css -->
.expect-long {
min-width: 0;
}
.expect-long *:has(.long) {
min-width: 0;
display: flex;
}
.long {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.nav-item:has(.long) {
display: flex;
align-items: center;
}
.navbar-collapse [role="search"] {
flex-shrink: 0;
}
.wrapper {
display: flex;
}
.wrapper>* {
padding: 5px 15px;
}
.child1 {
background: red;
}
.child2 {
background: lightblue;
}
.child3 {
background: green;
}
<!-- language: lang-html -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" />
<nav class="navbar navbar-expand-lg bg-body-tertiary">
<div class="container-fluid">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse expect-long" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
Dropdown
</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#">Action</a></li>
<li><a class="dropdown-item" href="#">Another action</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="#">Something else here</a></li>
</ul>
</li>
<li class="nav-item">
<div class="wrapper">
<div class="child1">child1</div>
<div class="child2">
<div>
<div>
<div>
<div class="long">long long long long long long long long long long long long long long long long long long long long text</div>
</div>
</div>
<div>a</div>
</div>
</div>
<div class="child3">child3</div>
</div>
</li>
</ul>
<div class="d-flex" role="search">
<input class="form-control me-2" type="search" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success" type="submit" onclick="changeItem()">Change</button>
</div>
</div>
</div>
</nav>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js"></script>
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论