การรวม CSS Pseudo-elements“: after” the“: last-child”


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 (หรือ codebehind ถ้าเป็นมากกว่า HTML ธรรมดา) CSS สำหรับการจัดรูปแบบ :)
Zyphrax

16
ฉัน ... โดยส่วนตัวมักจะโต้แย้งว่าในรายการการจัดรูปแบบเป็นสิ่งที่ดีไม่ใช่สิ่งจำเป็น ในกรณีนี้การใช้ CSS ช่วยให้สามารถเพิ่มหรือลบออกจากรายการได้ง่ายขึ้นกว่าการใช้ HTML หรือการเข้ารหัสฝั่งเซิร์ฟเวอร์ แต่ฉันก็แปลกแบบนั้นบางครั้งและตรงไปตรงมา ymmv ฯลฯ ... =)
เดวิดบอกว่าคืนสถานะโมนิกา

9
และ +1 สำหรับการใช้ Oxford Comma! :)
Brandon Rhodes

5
+1 สำหรับ "+1 สำหรับ Oxford Comma" ไม่เคยได้ยินเกี่ยวกับเรื่องนี้ (ฉันไม่ใช่คนพื้นเมือง) แต่การค้นหาวิกิอย่างรวดเร็วบอกว่าเป็นเรื่องธรรมชาติเพราะไม่ได้ใช้ในหลายภาษา ตลกดีที่เราสามารถเรียนรู้ปัญหา CSS แบบ stack-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ไม่ได้
Richard Ayotte

1
โปรดทราบ:last-childว่าไม่ได้เป็นของข้อกำหนด CSS3 ดังนั้นจึงไม่รองรับ IE8 และเวอร์ชันก่อนหน้า
Cthulhu

23

ฉันชอบสิ่งนี้สำหรับรายการใน <เมนู> อิลิเมนต์ พิจารณามาร์กอัปต่อไปนี้:

<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

และนี่เป็นไปได้เพราะสิ่งที่ Martin Atkins อธิบายในความคิดเห็นของเขา

โปรดสังเกตว่าใน 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
นี่เป็น "มุมของตัวเลือก nit-picker" เล็กน้อย แต่ "last-child" เป็นคลาสหลอกในขณะที่ "before" และ "after" เป็นองค์ประกอบหลอก ความแตกต่างคือคลาสหลอกเป็นข้อ จำกัด เพิ่มเติมขององค์ประกอบที่มีอยู่ในขณะที่องค์ประกอบหลอกเป็นองค์ประกอบใหม่ทั้งหมดในโครงสร้างการนำเสนอที่สร้างขึ้นใน CSS แทนที่จะเป็น HTML คุณสามารถรวมสิ่งเหล่านี้ด้วยเหตุนี้: last-childเป็นตัวปรับแต่งบนliและหลังจากที่คุณเลือกliองค์ประกอบทั้งหมดที่เป็นลูกสุดท้ายแล้วคุณจะเลือก (และสร้างโดยปริยาย) องค์ประกอบใหม่ก่อนและหลังแต่ละองค์ประกอบ
Martin Atkins

ฉันรู้ว่าคุณอาจลืมหัวข้อนี้ไปนานแล้ว แต่เนื่องจากคุณได้กล่าวว่ารายการของคุณมีความยาวผันแปรจึงควรชี้ให้เห็นว่าในบริบทส่วนใหญ่รายการที่มีสองรายการจะไม่ถูกต้องเมื่อใช้ลูกน้ำในภาษาอังกฤษ กล่าวอีกนัยหนึ่งถ้าคุณต้องการ "ขนมปังและเนย" มากกว่า "ขนมปังและเนย" - จากนั้นโซลูชันส่วนใหญ่ที่ให้ไว้ที่นี่จะไม่สมบูรณ์ ฉันได้หาวิธีแก้ไขและโพสต์ไว้ด้านล่างเพื่อเป็นคำตอบเผื่อว่าจะช่วยให้ใครก็ตามที่ยังคงมองหาเรื่องนี้อยู่ไกล ๆ
Matt Wagner

6

เพียงแค่พูดถึงใน CSS 3

:หลังจาก

ควรใช้แบบนี้

::หลังจาก

จาก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: "."; }

3
ทุกเบราว์เซอร์ที่รองรับ::ไวยากรณ์ CSS3 แบบdouble colon ยังรองรับเฉพาะ:ไวยากรณ์ แต่ IE 8 รองรับ single-colon เท่านั้นดังนั้นในตอนนี้ขอแนะนำให้ใช้ single-colon เพื่อการสนับสนุนเบราว์เซอร์ที่ดีที่สุด ::เป็นรูปแบบใหม่ที่เยื้องเพื่อแยกเนื้อหาหลอกจากตัวเลือกหลอก หากคุณไม่ต้องการการสนับสนุน IE 8 อย่าลังเลที่จะใช้ดับเบิ้ลโคลอน จากบทความนี้
JohnnyQ

2
IE 8 ไม่ใช่ผู้เล่นอีกต่อไปในแง่ของมาตรฐานเบราว์เซอร์ ไม่รองรับโดย Microsoft และไม่รองรับ HTML5 หรือ CSS3 (องค์ประกอบหลอกการแปลง ฯลฯ ) ฉันเคยทำงานหลายอย่างเกี่ยวกับความเข้ากันได้แบบย้อนหลังเมื่อถึงปีที่แล้วโดยย้อนกลับไปที่ IE6 / IE7 (ผ่าน Modernizr.) เรามาไกลมากแล้วและหากคุณตั้งใจให้ไซต์ของคุณนำเสนอตัวตนออนไลน์ในระยะยาวโดยที่ไม่กลายเป็นวิธีแก้สายตาสั้นเพียงแค่พิจารณารายได้ที่คุณจะได้รับจากผู้ที่ใช้ IE8 Nada แม้แต่ผู้สูงอายุที่มีอายุ 20 ปีขึ้นไปก็ใช้แท็บเล็ตและแล็ปท็อปแบบ 2-in-1 ในขณะนี้
Steven Ventimiglia

2

การเพิ่มคำตอบอื่นสำหรับคำถามนี้เพราะฉันต้องการสิ่งที่ @derek ต้องการอย่างแม่นยำและฉันได้รับคำตอบเพิ่มเติมก่อนที่จะเห็นคำตอบที่นี่ โดยเฉพาะผมจำเป็นต้องมี CSS ที่อาจยังบัญชีสำหรับกรณีที่มีตรงสองรายการที่จุลภาคไม่ต้องการ ตัวอย่างเช่นบรรทัดการประพันธ์บางรายการที่ฉันต้องการสร้างจะมีลักษณะดังนี้:

ผู้เขียนคนหนึ่ง: By Adam Smith.

ผู้เขียนสองคน: By Adam Smith and Jane Doe.

ผู้เขียนสามคน: By Adam Smith, Jane Doe, and Frank Underwood.

วิธีแก้ปัญหาที่ให้ไว้ที่นี่ใช้งานได้สำหรับผู้เขียน 1 คนและผู้แต่ง 3 คนขึ้นไป แต่ละเลยที่จะพิจารณากรณีของผู้เขียน 2 คนโดยที่รูปแบบ "Oxford Comma" (หรือที่เรียกว่าสไตล์ "Harvard Comma" ในบางส่วน) ไม่สามารถใช้ได้ - กล่าวคือไม่ควรมีเครื่องหมายจุลภาคก่อนการรวม

หลังจากช่วงบ่ายของการซ่อมแซมฉันได้พบกับสิ่งต่อไปนี้:

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

มันจะแสดง bylines ตามที่ฉันได้ระบุไว้ข้างต้น

ในท้ายที่สุดฉันยังต้องกำจัดช่องว่างระหว่าง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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.