CSS 在中间裁剪字符串
CSS crop string in the middle
我使用 css text-overflow: ellipsis.
裁剪了一个大文件名
<style>
#fileName {
width: 100px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
</style>
<div id="fileName"> This is the big name of my file.txt</div>
所以我有这个输出
This is the bi...
但我想保留文件扩展名并有这样的东西
This is the... le.txt
是否可以只使用 CSS?
由于我的文件始终是 txt,我尝试使用 text-overflow: string
,但它似乎只适用于 Firefox:
text-overflow: '*.txt';
这是我能想到的最好的...可能值得尝试清理第二个跨度的前缘...
CSS
#fileName span {
white-space: nowrap;
overflow: hidden;
display:inline-block;
}
#fileName span:first-child {
width: 100px;
text-overflow: ellipsis;
}
#fileName span + span {
width: 30px;
direction:rtl;
text-align:right;
}
HTML
<div id="fileName">
<span>This is the big name of my file.txt</span>
<span>This is the big name of my file.txt</span>
</div>
JavaScript 选项:
var cropWithExtension = function(value, maxChars, trailingCharCount) {
var result = value;
if(value.length > maxChars){
var front = value.substr(0, value.length - (maxChars - trailingCharCount - 3));
var mid = "...";
var end = value.substr(-trailingCharCount);
result = front + mid + end;
}
return result;
}
var trimmedValue = cropWithExtension("This is the big file.txt", 21, 6);
这是一个干净的 CSS 解决方案,使用 data-*
attribute 和两个 ::after
伪元素。我还添加了一个可选的悬停并显示所有文本(显示全文时需要删除 #fileName::after
伪元素)。
示例 1
#fileName {
position: relative;
width: 100px;
}
#fileName p {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
#fileName:after {
content: attr(data-filetype);
position: absolute;
left: 100%;
top: 0;
}
/*Show on hover*/
#fileName:hover {
width: auto
}
#fileName:hover:after {
display: none;
}
<div id="fileName" data-filetype="txt">
<p>This is the big name of my file.txt</p>
</div>
更进一步——当文件名很短时隐藏附加的文件类型
#fileName p::after
被赋予了与文本背景相匹配的背景颜色。当文件名很短因此不会被 overflow: hidden
.
截断时,这会覆盖“.txt”
注意 padding-right: 22px
,这会将“.txt”推到省略号之外。
请参阅下面的示例 2 和 3,了解不同浏览器支持的不同方法。似乎不可能在所有浏览器中愉快地隐藏“.txt”。
示例 2
浏览器兼容性: Chrome 和 Firefox。
#fileName p::after
被赋予了与文本背景相匹配的背景颜色。当文件名很短因此不会被 overflow: hidden
.
截断时,这会覆盖“.txt”
注意每个 ::after
伪元素上的 padding-right
。 padding-right: 22px
将“.txt”推到省略号之外,padding-right: 100%
给出覆盖伪元素的宽度。 padding-right: 100%
不适用于 Edge 或 IE 11。
#fileName {
position: relative;
width: 122px;
}
#fileName::after {
content: attr(data-filetype);
position: absolute;
right: 0;
top: 0;
}
#fileName p {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
padding-right: 22px;
}
#fileName p::after {
content: '';
background: #FFF;
position: relative;
padding-right: 100%;
z-index: 1;
}
/*Show on hover*/
#fileName:hover {
width: auto;
}
/*Hide .txt on hover*/
#fileName:hover::after {
display: none;
}
<div id="fileName" data-filetype=".txt">
<p>This is the big name of my file.txt</p>
</div>
<div id="fileName" data-filetype=".txt">
<p>Short.txt</p>
</div>
示例 3
浏览器兼容性: IE 11、Edge 和 Chrome。
#fileName p::after
上的 content: ... unholy amount of ...
赋予它宽度。这与 display: inline-block
一起是目前唯一适用于 Edge 浏览器/IE 11 以及 Chrome 的方法。 display: inline-block
在 Firefox 上打破了这个方法并且 .txt
不包含在短文件名中。
#fileName {
position: relative;
width: 122px;
}
#fileName::after {
content: attr(data-filetype);
position: absolute;
right: 0;
top: 0;
padding-right: 10px; /*Fixes Edge Browser*/
}
#fileName p {
white-space: nowrap;
overflow: hidden;
padding-right: 22px;
text-overflow: ellipsis;
}
#fileName p::after {
content: '.........................................................................................................................';/*Fixes Edge Browser*/
background: #FFF;
position: relative;
display: inline-block;/*Fixes Edge Browser*/
z-index: 1;
color: #FFF;
}
/*Show on hover*/
#fileName:hover {
width: auto
}
#fileName:hover::after {
display: none;
}
<div id="fileName" data-filetype=".txt">
<p>This is the big name of my file.txt</p>
</div>
<div id="fileName" data-filetype=".txt">
<p>Short.txt</p>
</div>
对于适用于流动布局的解决方案,我想出了一些使用 flexbox 的东西。明显的缺点是需要三个元素。明显的优势:如果有足够的空间,所有内容都会显示出来。根据具体情况,可能需要为段落添加额外的 white-space 规则以及第一个跨度的最小宽度。
<p><span>Long text goes in here except for the</span><span>very end</span></p>
p {display:flex}
p span:first-child {flex-shrink:1; text-overflow: ellipsis; overflow: hidden}
附录:严格来说,flex-shrink 甚至不是必需的,因为它无论如何都是 flex-items 的默认行为。然而,在 IE10 中并非如此。在这种情况下,前缀也是必要的。
这是另一个对我很有效的建议:
<div style="width:100%;border:1px solid green;display:inline-flex;flex-wrap:nowrap;">
<div style="flex: 0 1 content;text-overflow: ellipsis;overflow:hidden;white-space:nowrap;"> Her comes very very very very very very very very very very very very very very very very very very very long </div>
<div style="flex: 1 0 content;white-space:nowrap;"> but flexible line</div>
</div>
输入---这是一个非常非常非常非常大的file.txt
要截断上面的文件名,请使用下面的 javascript
输出---这是一个非常...大的file.txt
var selectedFileName = getItemSelected();//Input
$scope.referenceFileName =getItemSelected();
var len = selectedFileName.length;
if(len > 30){
selectedFileName = selectedFileName.substr(0,15)+'... '+selectedFileName.substr(len-15,15);
}
$scope.fileName = selectedFileName;
**
Note:
**在json---后端传递$scope.referenceFileName
$scope.fileName
这将是---前端
这是一个使用 flexbox
的解决方案,并且是动态的(例如,当用户调整浏览器 window 大小时有效)。缺点是省略号后面的文字是固定大小的,不能把省略号放在正中间。
CSS
.middleEllipsis {
margin: 10px;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: flex-start;
}
.start {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
flex-shrink: 1;
}
.end {
white-space: nowrap;
flex-basis: content;
flex-grow: 0;
flex-shrink: 0;
}
HTML
<div class="middleEllipsis">
<div class="start">This is a really long file name, really long really long really long</div><div class="end">file name.txt</div>
</div>
在 jsfiddle 上调整 right-hand 边框的大小以查看效果:
https://jsfiddle.net/L9sy4dwa/1/
如果您愿意滥用 direction: rtl
,您甚至可以将省略号放在文本中间,对您的 CSS:
做一些小改动
.middleEllipsis {
margin: 10px;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: flex-start;
}
.middleEllipsis > .start {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
flex-shrink: 1;
}
.middleEllipsis > .end {
white-space: nowrap;
flex-basis: content;
flex-grow: 0;
flex-shrink: 1;
align: right;
overflow: hidden;
direction: rtl;
}
您可以在 https://i.stack.imgur.com/CgW24.gif.
上看到这个样子的 gif 动画
这是一个展示这种方法的 jsfiddle:
我尝试了其中一些 CSS 方法,但问题是如果文本很短,您将得到“short text short text”而不是“short text”。
所以我采用了 CSS + JS 方法。
JS(我编辑了 Jeremy Friesen 的以修复某些情况):
const shrinkString = (originStr, maxChars, trailingCharCount) => {
let shrinkedStr = originStr;
const shrinkedLength = maxChars - trailingCharCount - 3;
if (originStr.length > shrinkedLength) {
const front = originStr.substr(0, shrinkedLength);
const mid = '...';
const end = originStr.substr(-trailingCharCount);
shrinkedStr = front + mid + end;
}
return shrinkedStr;
}
HTML:
<div>
<h5>{shrinkString("can be very long of short text", 50, 15)} </h5>
</div>
CSS:
div {
width: 200px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
希望对您有所帮助。对不起格式。这是我对 SO 的第一个回答。
接受答案很好。尽管对于浏览器兼容性,您可以检测是否截断。使整个 CSS 成为条件。
const wrap = document.getElementById('filenameText');
if (wrap.offsetWidth >= wrap.scrollWidth) {
this.truncation = false;
}
<div
:data-filetype="data-filetype"
:class="[truncation && 'truncateFilenamClass']"
>
我发现 css 解决方案有很多错误且难以维护,因为您需要添加属性或元素来分隔文本。
我构建了一个非常简单的 Javascript 来处理它。发送您的文本和文本的最大长度,您会在中间截断文本。
const truncateMiddle = (text, maxCharacters) => {
const txtLength = text.length; // Length of the incoming text
const txtLengthHalf = maxCharacters ? Math.round(maxCharacters / 2) : Math.round(txtLength / 2); // set max txtHalfLength
return text.substring(0, (txtLengthHalf -1)).trim() + '...' + text.substring((txtLength - txtLengthHalf) + 2, txtLength).trim() //Return the string
}
truncateMiddle('Once opon a time there was a little bunny', 10);
Returns: 一次...nny
缺点?当然,它需要更多功能才能响应。
CSS 很好,但我认为您必须在 JavaScript 之前完成以获得更准确的结果。
为什么?
因为,用 JS 你可以控制单词的第一个和最后一个文本的数量。
这只是 2 行 JavaScript 代码,用于按照您定义的方式裁剪字符串:-
let fileName=document.getElementById('fileName')
fileName.innerHTML=fileName.innerHTML.substring(1, 10)+'...'+fileName.innerHTML.slice(-2)
<div id="fileName"> This is the big name of my file.txt</div>
此外,您可以根据需要选择第一个 n
个单词,而不是使用 JS 的前几个 letter/characters 个单词。
这是谁的JS代码:-
let fileName=document.getElementById('fileName')
let Words=fileName.innerHTML.split(" ")
let i=0;
fileName.innerHTML=''
Words.forEach(e => {
i++
if(i<5)
fileName.innerHTML+=e+' '
});
fileName.innerHTML+='...'
<div id="fileName"> This is the big name of my file.txt</div>
我使用 css text-overflow: ellipsis.
裁剪了一个大文件名<style>
#fileName {
width: 100px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
</style>
<div id="fileName"> This is the big name of my file.txt</div>
所以我有这个输出
This is the bi...
但我想保留文件扩展名并有这样的东西
This is the... le.txt
是否可以只使用 CSS?
由于我的文件始终是 txt,我尝试使用 text-overflow: string
,但它似乎只适用于 Firefox:
text-overflow: '*.txt';
这是我能想到的最好的...可能值得尝试清理第二个跨度的前缘...
CSS
#fileName span {
white-space: nowrap;
overflow: hidden;
display:inline-block;
}
#fileName span:first-child {
width: 100px;
text-overflow: ellipsis;
}
#fileName span + span {
width: 30px;
direction:rtl;
text-align:right;
}
HTML
<div id="fileName">
<span>This is the big name of my file.txt</span>
<span>This is the big name of my file.txt</span>
</div>
JavaScript 选项:
var cropWithExtension = function(value, maxChars, trailingCharCount) {
var result = value;
if(value.length > maxChars){
var front = value.substr(0, value.length - (maxChars - trailingCharCount - 3));
var mid = "...";
var end = value.substr(-trailingCharCount);
result = front + mid + end;
}
return result;
}
var trimmedValue = cropWithExtension("This is the big file.txt", 21, 6);
这是一个干净的 CSS 解决方案,使用 data-*
attribute 和两个 ::after
伪元素。我还添加了一个可选的悬停并显示所有文本(显示全文时需要删除 #fileName::after
伪元素)。
示例 1
#fileName {
position: relative;
width: 100px;
}
#fileName p {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
#fileName:after {
content: attr(data-filetype);
position: absolute;
left: 100%;
top: 0;
}
/*Show on hover*/
#fileName:hover {
width: auto
}
#fileName:hover:after {
display: none;
}
<div id="fileName" data-filetype="txt">
<p>This is the big name of my file.txt</p>
</div>
更进一步——当文件名很短时隐藏附加的文件类型
#fileName p::after
被赋予了与文本背景相匹配的背景颜色。当文件名很短因此不会被 overflow: hidden
.
注意 padding-right: 22px
,这会将“.txt”推到省略号之外。
请参阅下面的示例 2 和 3,了解不同浏览器支持的不同方法。似乎不可能在所有浏览器中愉快地隐藏“.txt”。
示例 2
浏览器兼容性: Chrome 和 Firefox。
#fileName p::after
被赋予了与文本背景相匹配的背景颜色。当文件名很短因此不会被 overflow: hidden
.
注意每个 ::after
伪元素上的 padding-right
。 padding-right: 22px
将“.txt”推到省略号之外,padding-right: 100%
给出覆盖伪元素的宽度。 padding-right: 100%
不适用于 Edge 或 IE 11。
#fileName {
position: relative;
width: 122px;
}
#fileName::after {
content: attr(data-filetype);
position: absolute;
right: 0;
top: 0;
}
#fileName p {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
padding-right: 22px;
}
#fileName p::after {
content: '';
background: #FFF;
position: relative;
padding-right: 100%;
z-index: 1;
}
/*Show on hover*/
#fileName:hover {
width: auto;
}
/*Hide .txt on hover*/
#fileName:hover::after {
display: none;
}
<div id="fileName" data-filetype=".txt">
<p>This is the big name of my file.txt</p>
</div>
<div id="fileName" data-filetype=".txt">
<p>Short.txt</p>
</div>
示例 3
浏览器兼容性: IE 11、Edge 和 Chrome。
#fileName p::after
上的 content: ... unholy amount of ...
赋予它宽度。这与 display: inline-block
一起是目前唯一适用于 Edge 浏览器/IE 11 以及 Chrome 的方法。 display: inline-block
在 Firefox 上打破了这个方法并且 .txt
不包含在短文件名中。
#fileName {
position: relative;
width: 122px;
}
#fileName::after {
content: attr(data-filetype);
position: absolute;
right: 0;
top: 0;
padding-right: 10px; /*Fixes Edge Browser*/
}
#fileName p {
white-space: nowrap;
overflow: hidden;
padding-right: 22px;
text-overflow: ellipsis;
}
#fileName p::after {
content: '.........................................................................................................................';/*Fixes Edge Browser*/
background: #FFF;
position: relative;
display: inline-block;/*Fixes Edge Browser*/
z-index: 1;
color: #FFF;
}
/*Show on hover*/
#fileName:hover {
width: auto
}
#fileName:hover::after {
display: none;
}
<div id="fileName" data-filetype=".txt">
<p>This is the big name of my file.txt</p>
</div>
<div id="fileName" data-filetype=".txt">
<p>Short.txt</p>
</div>
对于适用于流动布局的解决方案,我想出了一些使用 flexbox 的东西。明显的缺点是需要三个元素。明显的优势:如果有足够的空间,所有内容都会显示出来。根据具体情况,可能需要为段落添加额外的 white-space 规则以及第一个跨度的最小宽度。
<p><span>Long text goes in here except for the</span><span>very end</span></p>
p {display:flex}
p span:first-child {flex-shrink:1; text-overflow: ellipsis; overflow: hidden}
附录:严格来说,flex-shrink 甚至不是必需的,因为它无论如何都是 flex-items 的默认行为。然而,在 IE10 中并非如此。在这种情况下,前缀也是必要的。
这是另一个对我很有效的建议:
<div style="width:100%;border:1px solid green;display:inline-flex;flex-wrap:nowrap;">
<div style="flex: 0 1 content;text-overflow: ellipsis;overflow:hidden;white-space:nowrap;"> Her comes very very very very very very very very very very very very very very very very very very very long </div>
<div style="flex: 1 0 content;white-space:nowrap;"> but flexible line</div>
</div>
输入---这是一个非常非常非常非常大的file.txt
要截断上面的文件名,请使用下面的 javascript
输出---这是一个非常...大的file.txt
var selectedFileName = getItemSelected();//Input
$scope.referenceFileName =getItemSelected();
var len = selectedFileName.length;
if(len > 30){
selectedFileName = selectedFileName.substr(0,15)+'... '+selectedFileName.substr(len-15,15);
}
$scope.fileName = selectedFileName;
**
Note:
**在json---后端传递$scope.referenceFileName
$scope.fileName
这将是---前端
这是一个使用 flexbox
的解决方案,并且是动态的(例如,当用户调整浏览器 window 大小时有效)。缺点是省略号后面的文字是固定大小的,不能把省略号放在正中间。
CSS
.middleEllipsis {
margin: 10px;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: flex-start;
}
.start {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
flex-shrink: 1;
}
.end {
white-space: nowrap;
flex-basis: content;
flex-grow: 0;
flex-shrink: 0;
}
HTML
<div class="middleEllipsis">
<div class="start">This is a really long file name, really long really long really long</div><div class="end">file name.txt</div>
</div>
在 jsfiddle 上调整 right-hand 边框的大小以查看效果:
https://jsfiddle.net/L9sy4dwa/1/
如果您愿意滥用 direction: rtl
,您甚至可以将省略号放在文本中间,对您的 CSS:
.middleEllipsis {
margin: 10px;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: flex-start;
}
.middleEllipsis > .start {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
flex-shrink: 1;
}
.middleEllipsis > .end {
white-space: nowrap;
flex-basis: content;
flex-grow: 0;
flex-shrink: 1;
align: right;
overflow: hidden;
direction: rtl;
}
您可以在 https://i.stack.imgur.com/CgW24.gif.
上看到这个样子的 gif 动画这是一个展示这种方法的 jsfiddle:
我尝试了其中一些 CSS 方法,但问题是如果文本很短,您将得到“short text short text”而不是“short text”。
所以我采用了 CSS + JS 方法。 JS(我编辑了 Jeremy Friesen 的以修复某些情况):
const shrinkString = (originStr, maxChars, trailingCharCount) => {
let shrinkedStr = originStr;
const shrinkedLength = maxChars - trailingCharCount - 3;
if (originStr.length > shrinkedLength) {
const front = originStr.substr(0, shrinkedLength);
const mid = '...';
const end = originStr.substr(-trailingCharCount);
shrinkedStr = front + mid + end;
}
return shrinkedStr;
}
HTML:
<div>
<h5>{shrinkString("can be very long of short text", 50, 15)} </h5>
</div>
CSS:
div {
width: 200px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
希望对您有所帮助。对不起格式。这是我对 SO 的第一个回答。
接受答案很好。尽管对于浏览器兼容性,您可以检测是否截断。使整个 CSS 成为条件。
const wrap = document.getElementById('filenameText');
if (wrap.offsetWidth >= wrap.scrollWidth) {
this.truncation = false;
}
<div
:data-filetype="data-filetype"
:class="[truncation && 'truncateFilenamClass']"
>
我发现 css 解决方案有很多错误且难以维护,因为您需要添加属性或元素来分隔文本。
我构建了一个非常简单的 Javascript 来处理它。发送您的文本和文本的最大长度,您会在中间截断文本。
const truncateMiddle = (text, maxCharacters) => {
const txtLength = text.length; // Length of the incoming text
const txtLengthHalf = maxCharacters ? Math.round(maxCharacters / 2) : Math.round(txtLength / 2); // set max txtHalfLength
return text.substring(0, (txtLengthHalf -1)).trim() + '...' + text.substring((txtLength - txtLengthHalf) + 2, txtLength).trim() //Return the string
}
truncateMiddle('Once opon a time there was a little bunny', 10);
Returns: 一次...nny
缺点?当然,它需要更多功能才能响应。
CSS 很好,但我认为您必须在 JavaScript 之前完成以获得更准确的结果。 为什么? 因为,用 JS 你可以控制单词的第一个和最后一个文本的数量。 这只是 2 行 JavaScript 代码,用于按照您定义的方式裁剪字符串:-
let fileName=document.getElementById('fileName')
fileName.innerHTML=fileName.innerHTML.substring(1, 10)+'...'+fileName.innerHTML.slice(-2)
<div id="fileName"> This is the big name of my file.txt</div>
此外,您可以根据需要选择第一个 n
个单词,而不是使用 JS 的前几个 letter/characters 个单词。
这是谁的JS代码:-
let fileName=document.getElementById('fileName')
let Words=fileName.innerHTML.split(" ")
let i=0;
fileName.innerHTML=''
Words.forEach(e => {
i++
if(i<5)
fileName.innerHTML+=e+' '
});
fileName.innerHTML+='...'
<div id="fileName"> This is the big name of my file.txt</div>