Как ввести (с CSS) «20201231123456» в «20201231-123456»? - PullRequest
3 голосов
/ 18 марта 2020

«20201231123456» - это идентификатор версии, который отображается в виде текста c в элементе страницы. Сложно разобрать визуально, и мне было интересно, могу ли я использовать чистый CSS, чтобы отобразить его разбитым на его компоненты даты и времени ; то есть без необходимости изменять фактическое значение в источнике HTML?

Я пытался выполнить поиск, но либо я получаю результаты 2011 года, говоря, что это невозможно, но кто-то работает над этим, либо результаты, предлагающие перевод каждого персонажа в отдельную область.

Существует ли современное решение этой, казалось бы, простой идеи?

Бонус: Чтобы усложнить ситуацию, это переходит в длинную таблицу с другие вещи - и некоторые из идентификаторов версии представляют собой 5-ди git числа, а не дату-время, но они отображаются в том же типе элемента HTML. Может ли стиль элемента HTML соответствовать обоим форматам, чтобы "54321" оставался как есть, а "20201231123456" по-прежнему становился "20201231-123456"?

Ответы [ 3 ]

7 голосов
/ 19 марта 2020

Здесь есть CSS -только решение , которое работает как для длинных (14 символов), так и для коротких значений (менее 14 символов):

div {
  font-family: monospace, monospace;
  width: 15ch;
  overflow: hidden;
  letter-spacing: 20ch;
  text-shadow: 
    /* the date */
    -20ch 0, -40ch 0, -60ch 0, -80ch 0, -100ch 0, -120ch 0, -140ch 0,
    /* the time */
    -159ch 0, -179ch 0, -199ch 0, -219ch 0, -239ch 0, -259ch 0;
}
<div>20201231123456</div>

<div>12345</div>

Идея состоит в том, чтобы использовать моноширинный шрифт (одинаковой ширины для всех символов) и модуль ch, который позволит вам немного перемещать символы в упорядоченный мода. Установите фиксированную ширину контейнера, а затем разместите их достаточно, чтобы они были из коробки. Наконец, используйте text-shadow для проецирования одного символа за раз.

Я знаю, это может быть утомительно (и немного глупо), но это отчасти работает:)

Но вы хотели это с да sh, для этого используйте псевдоэлемент, такой как ::before или ::after:

div {
  font-family: monospace, monospace;
  width: 19ch;
  overflow: hidden;
  position: relative;
  letter-spacing: 20ch;
  text-shadow: 
    /* the date */
    -20ch 0, -40ch 0, -60ch 0, -80ch 0, -100ch 0, -120ch 0, -140ch 0,
    /* the time */
    -159ch 0, -179ch 0, -199ch 0, -219ch 0, -239ch 0, -259ch 0;
}

div::before {
  content: "-";
  position: absolute;
  left: 8ch;
}
<div>20201231123456</div>

А теперь для вишни сверху: используйте псевдоэлементы поля, чтобы нарисовать линии и двоеточия, чтобы полностью отформатировать дату. Хотя тогда он не будет работать на меньшие даты, только на длинные:

div {
  font-family: monospace, monospace;
  width: 19ch;
  overflow: hidden;
  position: relative;
  letter-spacing: 20ch;
  text-shadow: 
    /* the date */
    -20ch 0, -40ch 0, -60ch 0, -79ch 0, -99ch 0, -118ch 0, -138ch 0,
    /* the time */
    -157ch 0, -177ch 0, -196ch 0, -216ch 0, -235ch 0, -255ch 0;
}

div::before {
  content: "-:";
  position: absolute;
  text-shadow: 3ch 0, -12ch 0, -9ch 0;
  left: 4ch;
}
<div>20201231123456</div>
1 голос
/ 19 марта 2020

С одним CSS я не думаю, что это легко выполнимо,
с использованием JavaScript Строка / срез MDN это довольно просто:

const str = "20201231123456";
const [date, time] = [str.slice(0, 8), str.slice(8)];

console.log( `${date}-${time}` )

Или как:

const str = "20201231123456";
const res = /^(\d{8})(\d+)$/.exec(str).splice(1).join('-');

console.log(res)

Пример использования:

Скажем, идентификаторы версий находятся внутри указанного элемента c, например <span> или <td> с классом .vid:

const prettyVID = el => {
  const str = el.textContent.trim();
  const [Y, M, D, h, m, s] = str.match(/^\d{4}|\d{2}/g);
  const ISO8601 = `${Y}-${M}-${D}T${h}:${m}:${s}Z`;
  const custom  = `${Y}${M}${D}-${h}${m}${s}`;

  el.title = new Date(ISO8601).toLocaleString('en', {timeZone: 'UTC'});
  el.textContent = custom;
}


document.querySelectorAll('.vid').forEach(prettyVID);
th, td {padding: 8px;}
<table>
  <thead>
    <tr><th>App name</th><th>Version (Hover to see date)</th></tr>
  </thead>
  <tbody>
    <tr><td>Lorem</td><td class="vid">20201231091015</td></tr>
    <tr><td>Ipsum</td><td class="vid">20200224123456</td></tr>
  </tbody>
</table>
0 голосов
/ 19 марта 2020

Сложность заключается в том, что CSS не является подходящей технологией для этой задачи.

CSS имеет множество возможностей представления, , но ... самая маленькая частица атома c, которую вы можете создать в CSS, представляет собой HTML элемент, такой как <div> или <span> или <strong> et c.

Если, например, мы возьмите следующий <div> элемент:

<div>target text here</div>

мы можем использовать CSS для представления <div> любым количеством способов.

И если мы пометим его как:

<div><span>target</span> <span>text</span> <span>here</span></div>

тогда мы можем стилизовать любой или все элементы <span>.

Но мы не можем стилизовать любую часть разметки, которая меньше, чем элемент.


NB Мы могли бы утверждать, что существует ограниченное число (вполне конкретное c) исключений из окончательного утверждения, приведенного непосредственно выше, включая псевдоэлементы CSS ::first-letter и ::first-line.


Какой подход мы можем использовать, если не можем использовать CSS?

Как @BastianSpringer отмечает в комментариях выше, * 106 0 * имеет возможность создать желаемый эффект.

Рабочий пример:

let numbers = [...document.getElementsByClassName('number')];

for (let number of numbers) {

  numberText = number.textContent;

  if (numberText.length > 8) {
    let numberArray = numberText.split('');
    numberArray.splice(8, 0, '-');
    numberText = numberArray.join('');
    number.textContent = numberText;
  }
}
<p class="number">54321</p>
<p class="number">20201231123456</p>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...