Объединяя CSS псевдоэлементы, ": after" the ": last-child" - PullRequest
114 голосов
/ 28 февраля 2010

Я хочу создавать «грамматически правильные» списки с использованием CSS. Это то, что я до сих пор:

Теги <li> отображаются горизонтально с запятыми после них.

li { display: inline; list-style-type: none; }

li:after { content: ", "; }

Это работает, но я хочу, чтобы у "последнего ребенка" была точка вместо запятой. И, если возможно, я бы тоже хотел поставить «и» перед «последним ребенком». Списки, которые я разрабатываю, генерируются динамически, поэтому я не могу просто дать класс "последним детям". Вы не можете комбинировать псевдоэлементы, но это в основном тот эффект, которого я хочу достичь.

li:last-child li:before { content: "and "; }

li:last-child li:after { content: "."; }

Как мне сделать эту работу?

Ответы [ 8 ]

157 голосов
/ 28 февраля 2010

Это работает :) (Надеюсь, мульти-браузер, Firefox это нравится)

li { display: inline; list-style-type: none; }
li:after { content: ", "; }
li:last-child:before { content: "and "; }
li:last-child:after { content: "."; }
<html>
  <body>
    <ul>
      <li>One</li>
      <li>Two</li>
      <li>Three</li>
    </ul>
  </body>
</html>
21 голосов
/ 10 декабря 2011

Мне нравится это для элементов списка в

14 голосов
/ 16 сентября 2015

Старый поток, тем не менее, кто-то может извлечь выгоду из этого:

li:not(:last-child)::after { content: ","; }
li:last-child::after { content: "."; }

Это должно работать в CSS3 и [не проверено] CSS2.

11 голосов
/ 28 февраля 2010

Вы можете комбинировать псевдоэлементы! Извините, ребята, я понял это сам вскоре после публикации вопроса. Возможно, он используется реже из-за проблем совместимости.

li:last-child:before { content: "and "; }

li:last-child:after { content: "."; }

Это работает плавно. CSS просто потрясающий.

6 голосов
/ 21 декабря 2013

Просто чтобы упомянуть, в CSS 3

: * после 1004 *

следует использовать вот так

:: * после * 1010

С https://developer.mozilla.org/de/docs/Web/CSS/::after:

Нотация :: after была введена в CSS 3 для установления различение псевдоклассов и псевдоэлементов. Браузеры также принять обозначение: после того, как введено в CSS 2.

Так и должно быть:

li { display: inline; list-style-type: none; }
li::after { content: ", "; }
li:last-child::before { content: "and "; }
li:last-child::after { content: "."; }
2 голосов
/ 11 апреля 2018

Чтобы иметь что-то вроде Один, два и три , вам нужно добавить еще один стиль CSS

li:nth-last-child(2):after {
    content: ' ';
}

Это удалит запятую из второго последнего элемента.

Полный код

li {
  display: inline;
  list-style-type: none;
}

li:after {
  content: ", ";
}

li:nth-last-child(2):after {
  content: '';
}

li:last-child:before {
  content: " and ";
}

li:last-child:after {
  content: ".";
}
<html>

<body>
  <ul>
    <li>One</li>
    <li>Two</li>
    <li>Three</li>
  </ul>
</body>

</html>
2 голосов
/ 06 июня 2014

Добавление еще одного ответа на этот вопрос, потому что мне нужно было именно то, о чем просил @derek, и я уже прошел немного дальше, прежде чем увидел ответы здесь. В частности, мне нужен был CSS, который мог бы также учитывать для случая ровно два элемента списка, где запятая НЕ желательна. Например, некоторые авторские подписи, которые я хотел создать, выглядели бы следующим образом:

Один автор: By Adam Smith.

Два автора: By Adam Smith and Jane Doe.

Три автора: By Adam Smith, Jane Doe, and Frank Underwood.

Решения, уже приведенные здесь, работают для одного автора и для 3 или более авторов, но не учитывают случай с двумя авторами, когда стиль «Оксфордская запятая» (также известный как стиль «Гарвардская запятая» в некоторых частях) не не применяется - т. е. перед соединением не должно быть запятой.

После полудня, я придумал следующее:

<html>
 <head>
  <style type="text/css">
    .byline-list {
      list-style: none;
      padding: 0;
      margin: 0;
    }
    .byline-list > li {
      display: inline;
      padding: 0;
      margin: 0;
    }
    .byline-list > li::before {
      content: ", ";
    }
    .byline-list > li:last-child::before {
      content: ", and ";
    }
    .byline-list > li:first-child + li:last-child::before {
      content: " and ";
    }
    .byline-list > li:first-child::before {
      content: "By ";
    }
    .byline-list > li:last-child::after {
      content: ".";
    }
  </style>
 </head>
 <body>
  <ul class="byline-list">
   <li>Adam Smith</li>
  </ul>
  <ul class="byline-list">
   <li>Adam Smith</li><li>Jane Doe</li>
  </ul>
  <ul class="byline-list">
   <li>Adam Smith</li><li>Jane Doe</li><li>Frank Underwood</li>
  </ul>
 </body>
</html>

Отображает подписи, как я их выше.

В конце концов, мне также пришлось избавиться от любого пробела между li элементами, чтобы обойти раздражение: свойство inline-block в противном случае оставляло бы пробел перед каждой запятой. Вероятно, есть альтернативный приличный взлом для этого, но это не предмет этого вопроса, поэтому я оставлю это, чтобы кто-то еще ответил.

Скрипка здесь: http://jsfiddle.net/5REP2/

0 голосов
/ 04 декабря 2013

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

Итак, изменение от:

  • Элемент списка 1
  • Элемент списка 2
  • Элемент списка 3

до:

Элемент списка 1; Элемент списка 2; Элемент списка 3.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...