Объединение псевдоэлементов CSS: "после" ": последний-ребенок"

Я хочу сделать "грамматически правильные" списки с помощью 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: "."; }

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

Ответ 1

Это работает:) (надеюсь, много браузер, 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>

Ответ 2

Мне нравится это для пунктов списка в меню & lt; menu & gt; элементы. Рассмотрим следующую разметку:

<menu>
  <li><a href="/member/profile">Profile</a></li>
  <li><a href="/member/options">Options</a></li>
  <li><a href="/member/logout">Logout</a></li>
</menu>

Я стилизую его с помощью следующего CSS:

menu > li {
  display: inline;
}

menu > li::after {
  content: ' | ';
}

menu > li:last-child::after {
  content: '';
}

Это отобразит:

Profile | Options | Logout

И это возможно из-за того, что объяснил Мартин Аткинс в своем комментарии

Обратите внимание, что в CSS 2 вы бы использовали :after, а не ::after. Если вы используете CSS 3, используйте ::after (два полуколонна), потому что ::after является псевдоэлементом (один полуколонна для псевдоклассов).

Ответ 3

Старый поток, тем не менее кто-то может воспользоваться этим:

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

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

Ответ 4

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

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

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

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

Ответ 5

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

: после

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

:: после

Из https://developer.mozilla.org/de/docs/Web/CSS/::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: "."; }

Ответ 6

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

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

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

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

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

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

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

Ответ 7

Чтобы иметь что-то вроде один, два и три, вы должны добавить еще один стиль 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>

Ответ 8

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

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

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

в

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