Строка обрезки CSS в середине

У меня есть большое имя файла, которое я обрезаю, используя переполнение текста css: 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>

Итак, у меня есть этот вывод

Это би...

Но я хочу сохранить расширение файла и иметь что-то вроде этого

Это... le.txt

Это возможно только с помощью CSS?

Так как мои файлы всегда txt, я попытался использовать text-overflow: string, но похоже, что он работает только в Firefox:

 text-overflow: '*.txt';

Ответы

Ответ 1

Вот чистое решение CSS, использующее data-* и два ::after data-*. Я также добавил опциональное наведение и отобразил весь текст (#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>

Ответ 2

Это лучшее, что я могу придумать... Возможно, стоит попробовать очистить передний край второго пролета...

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>

http://jsfiddle.net/c8everqm/1/

Ответ 3

Вот еще одно предложение, которое хорошо сработало для меня:

<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;"> &nbsp;but flexible line</div>
</div>

Ответ 4

Здесь решение, которое использует flexbox и является динамическим (например, работает, когда пользователь изменяет размер окна браузера). Недостатком является то, что текст после многоточия имеет фиксированный размер, поэтому вы не можете поместить многоточие в точную середину текста.

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, чтобы увидеть эффект:

https://jsfiddle.net/L9sy4dwa/1/

Если вы хотите злоупотреблять направлением: 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;
}

Вы можете увидеть анимированный gif того, как это выглядит на https://i.stack.imgur.com/CgW24.gif.

Здесь jsfiddle, показывающий этот подход:

https://jsfiddle.net/b8seyre3/

Ответ 5

Вариант 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);

Ответ 6

Ввод ---This - очень очень очень большой файл file.txt

Чтобы усечь указанное выше имя файла, используйте приведенный ниже javascript

Выход ---This - очень... большой файл.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;

**

Заметка:

** Передайте $ scope.referenceFileName в json --- back end

$scope.fileName это будет --- front end

Ответ 7

Я попробовал некоторые из этих подходов CSS, но проблема в том, что если текст короткий, вы получите "короткий текст короткого текста" вместо "короткого текста".

Так что я пошел с подходом CSS + JS. JS (я редактировал Джереми Фризена, чтобы исправить некоторые случаи):

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)}&nbsp;</h5>
</div>

CSS:

div {
  width: 200px;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

Надеюсь, это поможет. Извините за формат. Это мой первый ответ на SO.

Ответ 8

Для решения, которое работает с жидкостными макетами, я придумал что-то, что использует flexbox. Очевидным недостатком является то, что необходимы три элемента. Очевидное преимущество: если будет достаточно места, все будет показано. В зависимости от обстоятельств может потребоваться дополнительное правило белого пространства для абзаца, а также минимальная ширина для первого диапазона.

<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}

ADDENDUM: Строго говоря, flex-shrink даже не требуется, потому что это поведение по умолчанию для гибких элементов. Однако это не так в IE10. В этом случае также требуется префикс.