Поєднуючи псевдоелементи CSS, ": після", ": остання дитина"


122

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

Як зробити цю роботу?


4
Ви дійсно не повинні використовувати для цього css.
Funky Dude

2
Я повинен трохи погодитися з Funky Dude. Краще зробити це в HTML (або в коді, якщо це більше, ніж звичайний HTML). CSS призначений для форматування :)
Zyphrax

16
Я ... особисто схильний стверджувати, що в списку форматування - це нікчемність, а не необхідність. У такому випадку за допомогою CSS можна зробити більш прості доповнення або видалення зі списку, ніж використання кодування html або сервера. Але мені таке дивно, іноді, і, чесно кажучи, ymmv, і т.
Д.

9
І +1 за використання команди Оксфорд Кома! :)
Брендон Родос

5
+1 для "+1 для Оксфордської коми". Ніколи про це не чув (я не рідний). Але швидкий пошук вікі говорить, що це природно, оскільки він не використовується в багатьох мовах. Смішно, про що можна дізнатися проблеми з CSS-googling;)
jakub.g

Відповіді:


168

Це працює :) (Я сподіваюся, що мульти браузер, 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
Аналогічна проблема є у випадку, коли ви розділяєте елементи меню символами труби. Це ж рішення працює. Але для остаточного атрибута контенту потрібно встановити значення {content: none;}, щоб усунути остаточний характер.
aridlehoover

2
Порядок теж важливий. li:last-child:afterпрацює, але li:after:last-childне робить.
Річард Айотт

1
Майте на увазі, що :last-childвін не належить до специфікації CSS3, тому він не підтримується IE8 та попередніми версіями.
Cthulhu

23

Мені це подобається для елементів списку в елементах <menu>. Розглянемо таку розмітку:

<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це псевдоелемент (одна напівколонка призначена для псевдокласів).


16

Стара нитка, проте хтось може скористатися цим:

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

Це має працювати в CSS3 та [неперевіреному] CSS2.


11

Ви можете комбінувати псевдо-елементи! Вибачте, хлопці, я зрозумів це сам, невдовзі після публікації запитання. Можливо, він рідше використовується через проблеми сумісності.

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

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

Це працює плавно. CSS - це дивовижно.


12
Це трохи «кут блохолов» А, але «останній дитина» насправді є псевдо- класу , в той час як «до» і «після» псевдо-елементів. Різниця полягає в тому, що псевдоклас - це додаткове обмеження для існуючого елемента, тоді як псевдоелемент фактично є абсолютно новим елементом у дереві презентації, який був сформований у CSS, а не в HTML. Ви можете комбінувати їх з цієї причини: the last-child- це модифікатор на li, а після того, як ви вибрали всі liелементи, які є останніми дітьми, ви виберете (і неявно створюєте) новий елемент до і після кожного.
Мартін Аткінс

Я знаю, що ви, мабуть, давно забули цей конкретний потік, але оскільки ви згадали, що ваші списки мають різну довжину, варто зазначити, що в більшості контекстів список з точно двома пунктами не буде правильним із комою англійською мовою. Іншими словами, якщо ви хотіли "хліба з маслом". а не "хліб та масло". - тоді більшість запропонованих тут рішень були б неповними. Я придумав спосіб його обійти і розмістив його нижче як відповідь, якщо це допомагає комусь, хто все ще дивиться так далеко вниз.
Метт Вагнер

6

Відзначимо, у 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: "."; }

3
Кожен браузер, який підтримує ::синтаксис CSS3 з подвійною двокрапкою, також підтримує лише :синтаксис, але IE 8 підтримує лише двокрапку, тому для кращої підтримки браузера рекомендується просто використовувати однократку. ::- це новіший формат з відступом для відмежування вмісту псевдо від псевдоселекторів. Якщо вам не потрібна підтримка IE 8, сміливо використовуйте подвійну двокрапку. З цієї статті
JohnnyQ

2
IE 8 вже не є програвачем з точки зору стандартів браузера. Не підтримується Microsoft і не підтримує HTML5 або CSS3 (псевдоелементи, перетворення тощо). До року назад я багато працював над зворотною сумісністю, повертаючись до IE6 / IE7 (через Modernizr.) Ми пройшли довгий шлях, і якщо ви плануєте, щоб ваш сайт довгостроково презентував свою інтернет-ідентичність - без того, щоб це стало короткозорим рішенням, - тоді просто врахуйте дохід, який ви заробляли б від того, хто використовує IE8. Нада. Навіть люди похилого віку, на 20 років відставши від часів, зараз використовують планшети та ноутбуки 2-в-1.
Стівен Вентимілія

2

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

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

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

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

Уже наведені тут рішення працюють для одного автора та для трьох і більше авторів, але нехтують обліком двох авторських випадків - де стиль "Оксфордська кома" (також відомий як стиль "Гарвардська кома" в деяких частинах) не застосовується - тобто не повинно бути кома перед сполучником.

Після обіду роздумів я придумав таке:

<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елементами, щоб обійти роздратування: властивість вбудованого блоку інакше залишать пробіл перед кожною комою. Напевно, є альтернативний гідний хакер для цього, але це не тема цього питання, тому я залишу це для того, щоб відповісти хтось інший.

Скрипаль тут: http://jsfiddle.net/5REP2/


2

Щоб мати щось на зразок один, два та три , слід додати ще один стиль 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>


0

Я використовую ту саму техніку в медіа-запиті, який фактично перетворює список куль у рядковий список на менших пристроях, оскільки вони економить місце.

Тож зміна від:

  • Елемент списку 1
  • Елемент списку 2
  • Пункт 3 списку

до:

Перелік пункту 1; Перелік пункту 2; Пункт 3 списку.


Він намагається зробити це за допомогою CSS. Ваш метод - це жорсткий код HTML. Цей метод зазвичай використовується для відображення навігації.
Sparatan117
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.