CSS Sözde öğelerini birleştirmek, ": sonra" ": son-çocuk"


122

CSS kullanarak "gramer açısından doğru" listeler yapmak istiyorum. Şu ana kadar sahip olduğum şey bu:

<li>Etiketler onlardan sonra virgül ile yatay olarak görüntülenir.

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

li:after { content: ", "; }

Bu işe yarıyor, ancak "son çocuğun" virgül yerine nokta olmasını istiyorum. Ve mümkünse, "son-çocuk" un önüne de "ve" koymak isterim. Biçimlendirdiğim listeler dinamik olarak oluşturuluyor, bu yüzden "son çocuklara" bir sınıf veremem. Sözde unsurları birleştiremezsiniz, ancak temelde elde etmek istediğim etki bu.

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

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

Bunu nasıl çalıştırırım?


4
bunun için gerçekten css kullanmamalısın.
Funky Dude

2
Funky Dude'a biraz katılıyorum. Bunu HTML'de (veya düz HTML'den fazlasıysa kod arkasında) yapmak daha iyi olacaktır. CSS biçimlendirme içindir :)
Zyphrax

16
Ben ... şahsen, bir listede biçimlendirmenin bir gereklilik değil, bir nezaket olduğunu iddia etme eğilimindeyim. CSS kullanmak, html veya sunucu tarafı kodlamayı kullanmaktan daha basit eklemelere veya listeden çıkarmalara izin verir. Ama bazen böyle tuhafım ve dürüst olmak gerekirse ymmv, vs ... =)
David, Monica'nın

9
Ve Oxford Virgülünü kullanmak için +1! :)
Brandon Rhodes

5
"Oxford Virgül için +1" için +1. Hiç duymadım (ben yerli değilim). Ancak hızlı wiki araması, pek çok dilde kullanılmadığı için bunun doğal olduğunu söylüyor. Birinin yığın-googling CSS sorunlarını öğrenebilecekleri komik;)
jakub.g

Yanıtlar:


168

Bu çalışıyor :) (Umarım çoklu tarayıcı, Firefox beğenir)

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
Benzer bir sorun, menü öğelerini dikey çizgi karakterleriyle ayırdığınız durumdur. Aynı çözüm işe yarar. Ancak, son boru karakterini ortadan kaldırmak için son içerik özniteliğinin {content: none;} olarak ayarlanması gerekir.
aridlehoover

2
Düzen de önemlidir. li:last-child:afterçalışır ama li:after:last-childçalışmaz.
Richard Ayotte

1
Bunun :last-childCSS3 spesifikasyonuna ait olmadığını unutmayın , bu nedenle IE8 ve önceki sürümler tarafından desteklenmez.
Cthulhu

23

Bunu <menu> öğelerindeki liste öğeleri için seviyorum. Aşağıdaki işaretlemeyi düşünün:

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

Aşağıdaki CSS ile biçimlendiriyorum:

menu > li {
  display: inline;
}

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

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

Bu şunu gösterecektir:

Profile | Options | Logout

Ve bu, Martin Atkins'in yorumunda açıkladığı şey sayesinde mümkün.

CSS 2'de kullanmayacağınızı :afterunutmayın ::after. CSS 3 kullanıyorsanız, ::after(iki yarım sütun) kullanın çünkü ::aftersözde bir öğedir (tek bir yarı sütun sözde sınıflar içindir).


16

Eski bir konu, yine de birileri bundan yararlanabilir:

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

Bu, CSS3 ve [test edilmemiş] CSS2'de çalışmalıdır.


11

Sen edebilirsiniz sözde unsurları birleştirmek! Üzgünüm çocuklar, soruyu gönderdikten kısa bir süre sonra bunu kendim çözdüm. Belki de uyumluluk sorunları nedeniyle daha az kullanılır.

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

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

Bu çok iyi çalışıyor. CSS biraz şaşırtıcı.


12
Bu biraz "nit-toplayıcı köşesi", ama "last-child" aslında bir sözde sınıftır , "before" ve "after" sözde öğelerdir. Aradaki fark, sözde sınıfın mevcut bir öğe üzerinde ek bir kısıtlama olması, sözde öğenin ise sunum ağacında HTML yerine CSS'de oluşturulan tamamen yeni bir öğedir. Bunları bu nedenle birleştirebilirsiniz: bu last-child, üzerinde bir değiştiricidir live lison alt öğe olan tüm öğeleri seçtikten sonra, her birinin öncesinde ve sonrasında yeni bir öğe seçersiniz (ve örtük olarak yaratırsınız).
Martin Atkins

Muhtemelen bu konuyu uzun zamandır unuttuğunuzu biliyorum, ancak listelerinizin değişken uzunlukta olduğundan bahsettiğiniz için, çoğu bağlamda tam olarak iki maddeden oluşan bir listenin İngilizce'de virgülle doğru olmayacağına işaret etmeye değer. Başka bir deyişle, "ekmek ve tereyağı" istiyorsan. "ekmek ve tereyağı" yerine. - o zaman burada sağlanan çözümlerin çoğu eksik olacaktır. Bunun etrafında bir yol buldum ve bir cevap olarak aşağıya gönderdim, eğer hala bu kadar aşağıya bakan birinin yardımcı olması durumunda.
Matt Wagner

6

CSS 3'te bahsetmek gerekirse

:sonra

böyle kullanılmalı

::sonra

Gönderen https://developer.mozilla.org/de/docs/Web/CSS/::after :

Sahte sınıflar ve sözde öğeler arasında bir ayrım yapmak için CSS 3'te :: after notasyonu tanıtıldı. Tarayıcılar ayrıca gösterimi kabul eder: CSS 2'de tanıtıldıktan sonra.

Bu yüzden olmalı:

li { display: inline; list-style-type: none; }
li::after { content: ", "; }
li:last-child::before { content: "and "; }
li:last-child::after { content: "."; }

3
Çift iki nokta üst üste ::CSS3 sözdizimini destekleyen her tarayıcı da yalnızca sözdizimini destekler :, ancak IE 8 yalnızca tek iki nokta üst üste işaretini destekler , bu nedenle şimdilik, en iyi tarayıcı desteği için yalnızca tek iki nokta üst üste kullanılması önerilir. ::sözde içeriği sözde seçicilerden ayırmak için girintilenen yeni biçimdir. IE 8 desteğine ihtiyacınız yoksa, çift iki nokta üst üste kullanmaktan çekinmeyin. Bu makaleden
JohnnyQ

2
IE 8 artık tarayıcı standartları açısından bir oyuncu değil. Microsoft tarafından desteklenmiyor ve HTML5 veya CSS3'ü (sözde öğeler, dönüştürmeler vb.) Desteklemiyor Bir yıl öncesine kadar geriye dönük uyumluluk konusunda çok iş yapıyordum, IE6 / IE7'ye (üzerinden Modernizr.) Uzun bir yol kat ettik ve sitenizin çevrimiçi kimliğini uzun vadede - kısa vadeli bir çözüm olmadan - sunmayı düşünüyorsanız, o zaman IE8 kullanan birinden kazanacağınız geliri düşünün. Nada. Zamanın 20 yıl gerisinde olan yaşlılar bile artık tablet ve 2'si 1 arada dizüstü bilgisayar kullanıyor.
Steven Ventimiglia

2

Bu soruya bir cevap daha eklemek, çünkü @derek'in tam olarak ne istediğine ihtiyacım vardı ve cevapları burada görmeden önce biraz daha ileri gitmiştim. Spesifik olarak, virgülün istenmediği tam olarak iki liste öğesiyle durumu da açıklayabilecek CSS'ye ihtiyacım vardı . Örnek olarak, üretmek istediğim bazı yazar imzaları şuna benzer:

Bir yazar: By Adam Smith.

İki yazar: By Adam Smith and Jane Doe.

Üç yazar: By Adam Smith, Jane Doe, and Frank Underwood.

Burada zaten verilen çözümler bir yazar ve 3 veya daha fazla yazar için işe yarıyor, ancak iki yazar vakasını açıklamayı ihmal ediyor — burada "Oxford Virgül" stili (bazı bölümlerde "Harvard Virgül" stili olarak da bilinir) geçerli değildir - yani, bağlantıdan önce virgül olmamalıdır.

Bir öğleden sonra kurcalamadan sonra şunu buldum:

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

İmza çizgilerini yukarıda anladığım gibi gösteriyor.

Sonunda, libir sıkıntının üstesinden gelmek için öğeler arasındaki boşluklardan da kurtulmak zorunda kaldım : aksi takdirde satır içi blok özelliği her virgülden önce bir boşluk bırakırdı. Muhtemelen bunun için iyi bir alternatif hack var ama bu sorunun konusu bu değil, bu yüzden bunu başka birinin cevaplaması için bırakacağım.

Burada keman çalın: http://jsfiddle.net/5REP2/


2

Bir, iki ve üç gibi bir şeye sahip olmak için bir tane daha css stili eklemelisiniz

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

Bu, virgülü ikinci son öğeden kaldırır.

Kodu tamamla

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

Aynı tekniği, bir madde işaretli listeyi daha küçük cihazlarda yer tasarrufu sağladıkları için bir satır içi listeye etkili bir şekilde dönüştüren bir medya sorgusunda kullanıyorum.

Yani şu durumdan değişiklik:

  • Liste öğesi 1
  • Liste öğesi 2
  • Liste öğesi 3

için:

Liste Öğesi 1; Liste Öğesi 2; Liste Öğesi 3.


Bunu CSS ile yapmaya çalışıyor. Yönteminiz sabit kodlu HTML'dir. Bu yöntem normalde Navigasyonu görüntülemek için kullanılır.
Sparatan117
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.