การข้ามข้อความหลายบรรทัดข้ามเบราว์เซอร์ที่มีจุดไข่ปลาต่อท้ายภายในความกว้างและความสูงคงที่


178

ฉันสร้างภาพสำหรับคำถามนี้เพื่อให้เข้าใจง่ายขึ้น

เป็นไปได้ไหมที่จะสร้างจุดไข่ปลาบน a <div>ด้วยความกว้างคงที่และหลายบรรทัด?

ข้อความล้น

ฉันลองใช้ปลั๊กอิน jQuery ที่นี่และที่นั่น แต่ไม่พบสิ่งที่ฉันกำลังมองหา ข้อเสนอแนะใด ๆ ไอเดีย?



1
และstackoverflow.com/questions/3922739/…สำหรับโซลูชัน css-only เท่านั้น
Evgeny

บทความที่เกี่ยวข้องcss-tricks.com/line-clampin
Adrien เป็น

2
สำหรับทุกคนที่กำลังมองหาสิ่งนี้ในช่วงกลางปี ​​2559 คำตอบสั้น ๆ คือ: ไม่สามารถทำได้ในเบราว์เซอร์ที่สง่างาม, CSS, วิธีเดียว วิธีแก้ปัญหาที่มักจะได้รับใกล้เคียงที่สุดคือ ( codepen.io/romanrudenko/pen/ymHFh ) ดังนั้น Goldbergian จึงทำให้ร่างกายของคุณเจ็บปวดและยังน่าเกลียดอยู่
konrad

คำตอบ:


91

เป็นแนวคิดพื้นฐานที่รวดเร็ว

ฉันกำลังทดสอบด้วยมาร์กอัปต่อไปนี้:

<div id="fos">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin nisi ligula, dapibus a volutpat sit amet, mattis et dui. Nunc porttitor accumsan orci id luctus. Phasellus ipsum metus, tincidunt non rhoncus id, dictum a lectus. Nam sed ipsum a lacus sodales eleifend. Vestibulum lorem felis, rhoncus elementum vestibulum eget, dictum ut velit. Nullam venenatis, elit in suscipit imperdiet, orci purus posuere mauris, quis adipiscing ipsum urna ac quam.</p>  
</div>

และ CSS:

#fos { width: 300px; height: 190px; overflow: hidden; }
#fos p { padding: 10px; margin: 0; }

การใช้ jQuery นี้จะบรรลุผลตามที่ต้องการ:

var $p = $('#fos p');
var divh = $('#fos').height();
while ($p.outerHeight() > divh) {
    $p.text(function (index, text) {
        return text.replace(/\W*\s(\S)*$/, '...');
    });
}

มันพยายามที่จะลบคำสุดท้ายของข้อความซ้ำ ๆ จนกว่าจะถึงขนาดที่ต้องการ เพราะน้ำล้น: ซ่อนเร้น; กระบวนการยังคงมองไม่เห็นและแม้เมื่อ JS ปิดผลลัพธ์ยังคง 'ถูกต้องด้วยสายตา' (โดยไม่ต้องมี "... " แน่นอน)

หากคุณรวมสิ่งนี้เข้ากับการตัดที่สมเหตุสมผลบนฝั่งเซิร์ฟเวอร์ (ที่เหลือเพียงค่าใช้จ่ายเล็ก ๆ ) จากนั้นจะทำงานเร็วขึ้น :)

อีกครั้งนี่ไม่ใช่วิธีแก้ปัญหาที่สมบูรณ์ แต่เป็นเพียงความคิด

UPDATE:เพิ่มjsFiddle สาธิต


1
ทางออกที่ดี @bazmegakapa ... แต่ฉันมีปัญหาบางอย่างที่พยายามปรับให้เข้ากับกรณีของฉัน ฉันมีความหลากหลายliและภายในของแต่ละคนมี a .blockและ a .block h2และฉันจำเป็นต้องใช้สิ่งนี้กับh2ภายใน.blockแต่ฉันไม่สามารถทำให้มันใช้งานได้ มันต่างกันไหมถ้ามีมากกว่าหนึ่ง.block h2?
Alex

1
ในกรณีของฉันมันทิ้งข้อความไว้แค่ 2 บรรทัดเมื่อควรมี 3. เห็นได้ชัดว่าคอนเทนเนอร์ของฉันมีขนาดเล็กกว่าเส้นheight*3โดยไม่กี่พิกเซล การแก้ไขที่ง่ายคือการเพิ่มพิกเซลเพียงไม่กี่พิกเซลdivh
Lukas LT

3
ฉันมีประสบการณ์ที่ไม่ดีในการวนซ้ำกับสคริปต์นี้เพราะข้อความมีเพียงคำเดียวที่ยาวมากดังนั้นการแทนที่ regexp ไม่ตรงกัน เพื่อหลีกเลี่ยงปัญหานี้ให้เพิ่มรหัสนี้หลังwhileบรรทัด:if(!$p.text().match(/\W*\s(\S)*$/)) break;
KrisWebDev

1
แม้ว่าจะไม่น่าจะเป็นปัญหาในกรณีนี้การอัปเดต DOM และการตรวจสอบเค้าโครงซ้ำ ๆ เป็นความคิดที่ไม่ดีเพราะอาจทำให้การทำงานช้าลง เพื่อลดสิ่งนี้คุณสามารถทำสิ่งที่คล้ายกับการค้นหาแบบไบนารี่: ทดสอบเพื่อดูว่าบล็อกข้อความเหมาะสมหรือไม่หรือแยกข้อความออกเป็นคำหรือตัวอักษรและกำหนดขอบเขต (ล่าง = 1 คำ / ตัวอักษรบน = ทุกคำ / ตัวอักษร) , while ((upper-lower)>1) {let middle=((lower+upper)/2)|0 /*|0 is quick floor*/; if (test(words.slice(0,middle)+'...')) {lower=middle;} else {upper=middle;}}. ตามที่ @KrisWebDev ค้นพบคุณจะต้องตรวจสอบคำยักษ์หนึ่งคำ
Chinoto Vokro

1
วิธีนี้ดีมาก ในกรณีของฉันฉันต้องติดตามข้อความต้นฉบับเพื่อที่ฉันจะสามารถตัดค่าข้อความทั้งหมดได้อย่างมีการตอบสนอง ดังนั้นเมื่อเพจโหลดฉันจะเก็บข้อความต้นฉบับไว้ในตัวแปรและก่อนที่ฉันจะรันตรรกะนี้ฉันต้องแน่ใจว่าได้ 'รีเฟรช' องค์ประกอบด้วยค่าข้อความดั้งเดิม เพิ่ม debounce และใช้งานได้อย่างยอดเยี่ยม
besseddrest

68

ลองใช้ปลั๊กอินjQuery.dotdotdot

$(".ellipsis").dotdotdot();

11
คุณออกเสียงอย่างไร จุดจุดจุดจุด?
JackAce

58
แย่จริงๆที่จะใช้> 600 บรรทัดของ js เพื่อแก้ปัญหาที่ควรแก้ไขโดย css
Jethro Larson

ฉันลองแล้วและใช้งานได้ดี ควรเป็นคำตอบที่ได้รับการยอมรับ
AbdelHady

1
ใช้งานได้ แต่ต้องแน่ใจว่าใช้เหตุการณ์ window.loaded และไม่ใช่ $ (document) .ready () เนื่องจากฟอนต์และทรัพยากรภายนอกอื่น ๆ อาจส่งผลต่อเค้าโครงของ HTML ของคุณ หาก dotdotdot ดำเนินการก่อนที่จะโหลดทรัพยากรเหล่านี้ข้อความจะไม่ถูกตัดทอนในตำแหน่งที่ถูกต้อง
วิส

10
นี่คือเครื่องมือเชิงพาณิชย์มีราคา $ 5 สำหรับไซต์เดียวและ $ 35 สำหรับหลายไซต์ การออกใบอนุญาตจะเป็นความเจ็บปวด ฉันคิดว่ามันฟรีและสามารถบูรณาการได้ทันทีไม่ใช่เช่นนั้น!
ยีน b

29

ไลบรารี Javascript สำหรับ "line clamping"

โปรดทราบว่า "การยึดสาย" เรียกอีกอย่างว่า "จุดไข่ปลาบนบล็อกของหลายบรรทัด" หรือ "จุดไข่ปลาแนวตั้ง"


github.com/BeSite/jQuery.dotdotdot


github.com/josephschmitt/Clamp.js


นี่คืออีกไม่กี่ฉันยังไม่ได้ตรวจสอบ:


โซลูชั่น CSS สำหรับการหนีบสาย

มีบางโซลูชั่น CSS การใช้งานที่ง่ายมี แต่ที่มีการสนับสนุนเบราว์เซอร์ที่น่าสงสาร-webkit-line-clamp ดูการสาธิตสดบนjsfiddle.net/AdrienBe/jthu55v7/

หลายคนพยายามอย่างมากเพื่อให้สิ่งนี้เกิดขึ้นโดยใช้ CSS เท่านั้น ดูบทความและคำถามเกี่ยวกับมัน:


สิ่งที่ฉันอยากจะแนะนำ

ง่าย ๆ เข้าไว้. ยกเว้นว่าคุณมีเวลาเหลือเฟือที่จะอุทิศให้กับคุณสมบัตินี้ให้หาทางออกที่ง่ายที่สุดและทดสอบแล้ว: CSS อย่างง่ายหรือไลบรารีจาวาสคริปต์ที่ผ่านการทดสอบอย่างดี

ไปสำหรับสิ่งที่แฟนซี / ซับซ้อน / ปรับแต่งสูงและคุณจะจ่ายราคานี้ลงถนน


คนอื่นทำอะไร

การจางหายไปอย่าง Airbnb อาจเป็นทางออกที่ดี มันอาจเป็น CSS พื้นฐานร่วมกับ jQuery พื้นฐาน จริงๆแล้วดูเหมือนว่าจะคล้ายกันมากโซลูชันนี้ใน CSSTricks มาก

AirBnb โซลูชัน "อ่านเพิ่มเติม"

โอ้และถ้าคุณมองหาแรงบันดาลใจในการออกแบบ:

  • smashingmagazine.com/2009/07/designing-read-more-and-continue-reading-links/ตั้งแต่ 2009 แม้ว่า ...
  • Dribbble อาจมีการออกแบบที่น่าสนใจ ... ฉันไม่สามารถหาวิธีรวบรวมได้ (ผ่านการค้นหาหรือแท็ก) อย่าลังเลที่จะแชร์ลิงก์ที่เกี่ยวข้อง

6

ไม่มีคุณสมบัติดังกล่าวใน HTML และสิ่งนี้น่าผิดหวังมาก

ฉันได้พัฒนาห้องสมุดเพื่อจัดการกับสิ่งนี้

  • Multiline text-overflow: ellipsis
  • เพิ่มข้อความหลายบรรทัดด้วยเทคโนโลยีที่ไม่รองรับ: SVG, Canvas
  • มีตัวแบ่งบรรทัดเดียวกันในข้อความ SVG ของคุณในการแสดง HTML และในการส่งออก PDF ของคุณ

ตรวจสอบเว็บไซต์ของฉันเพื่อดูภาพหน้าจอบทแนะนำและลิงก์ dowload


"ข้อผิดพลาดในการสร้างการเชื่อมต่อฐานข้อมูล" ... คุณอาจต้องการทำเหมือนคนอื่น ๆ และโฮสต์โครงการของคุณใน Github มันอาจจะดีกว่าสำหรับคุณและสำหรับชุมชน :)
Adrien เป็น

@AdrienBe ใช้ Github: github.com/rossille/jstextและคุณพูดถูก GitHub มีความเสถียรมากกว่าเว็บไซต์ของฉันฉันตั้งหน้า GitHub ให้เป็นลิงก์หลัก
Samuel Rossille

@SamuelRossille ข่าวดีขอบคุณสำหรับการอัพเดทอย่างรวดเร็ว!
Adrien เป็น

4

วิธีการแก้ปัญหา JS บริสุทธิ์ขึ้นอยู่กับวิธีการแก้ปัญหาของbažmegakapaและการล้างข้อมูลบางอย่างสำหรับผู้ที่พยายามให้ความสูง / ความสูงสูงสุดที่น้อยกว่าองค์ประกอบของความสูง:

  var truncationEl = document.getElementById('truncation-test');
  function calculateTruncation(el) {
    var text;
    while(el.clientHeight < el.scrollHeight) {
      text = el.innerHTML.trim();
      if(text.split(' ').length <= 1) {
        break;
      }
      el.innerHTML = text.replace(/\W*\s(\S)*$/, '...');
    }
  }

  calculateTruncation(truncationEl);

นี่เป็นโค้ดที่ไม่มีประสิทธิภาพมาก โดยวิธีการใช้ของ "ในขณะที่" ดูเป็นข้อผิดพลาดที่อาจเกิดขึ้นกับวงไม่มีที่สิ้นสุด
WebBrother

4

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

http://salzerdesign.com/blog/?p=453

แก้ไข: ขออภัยฉันไม่ทราบว่าลิงก์ไม่เพียงพอ การแก้ปัญหาคือการวาง div รอบข้อความและจัดวาง div เพื่อควบคุมโอเวอร์โฟลว์ ใน div ให้ใส่ div อื่นด้วยการไล่ระดับ "จาง" ซึ่งสามารถทำได้โดยใช้ CSS หรือรูปภาพ (สำหรับ IE เก่า) การไล่ระดับสีเริ่มจากโปร่งใสเป็นสีพื้นหลังของเซลล์ตารางและมีความกว้างมากกว่าจุดไข่ปลาเล็กน้อย หากข้อความยาวและล้นออกไปข้อความนั้นจะอยู่ในส่วน "จาง" และดูว่า "จาง" หากข้อความสั้นจางหายไปจะมองไม่เห็นจึงไม่มีปัญหา สามารถปรับสองคอนเทนเนอร์เพื่อให้แสดงหนึ่งหรือหลายบรรทัดโดยการตั้งค่าความสูงของคอนเทนเนอร์เป็นความสูงหลายบรรทัดของข้อความ div "จาง" สามารถจัดตำแหน่งให้ครอบคลุมเฉพาะบรรทัดสุดท้ายเท่านั้น


โปรดแบ่งปันส่วนสำคัญของโซลูชันของคุณไม่อนุญาตให้ใช้คำตอบเฉพาะลิงก์เท่านั้น
kapa

ลักษณะที่ยอดเยี่ยมของสิ่งนี้คือข้อความที่ไม่ได้ถูกตัดทอนดังนั้นหากผู้ใช้คัดลอกวางตารางเนื้อหาทั้งหมดจะปรากฏขึ้น
ต้นแบบ

แนวคิดที่ดีมาก มันยังกล่าวถึงในบทความนี้ ("หายไป" ทาง) ฉันเชื่อว่าcss-tricks.com/line-clampin
Adrien เป็น

4

นี่คือวิธี CSS บริสุทธิ์เพื่อบรรลุสิ่งนี้: http://www.mobify.com/blog/multiline-ellipsis-in-pure-css/

นี่คือบทสรุป:

ป้อนคำอธิบายรูปภาพที่นี่

<html>
<head>
<style>
    html, body, p { margin: 0; padding: 0; font-family: sans-serif;}

    .ellipsis {
        overflow: hidden;
        height: 200px;
        line-height: 25px;
        margin: 20px;
        border: 5px solid #AAA; }

    .ellipsis:before {
        content:"";
        float: left;
        width: 5px; height: 200px; }

    .ellipsis > *:first-child {
        float: right;
        width: 100%;
        margin-left: -5px; }        

    .ellipsis:after {
        content: "\02026";  

        box-sizing: content-box;
        -webkit-box-sizing: content-box;
        -moz-box-sizing: content-box;

        float: right; position: relative;
        top: -25px; left: 100%; 
        width: 3em; margin-left: -3em;
        padding-right: 5px;

        text-align: right;

        background: -webkit-gradient(linear, left top, right top,
            from(rgba(255, 255, 255, 0)), to(white), color-stop(50%, white));
        background: -moz-linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white);           
        background: -o-linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white);
        background: -ms-linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white);
        background: linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white); }
</style>
</head>
<body>
    <div class="ellipsis">
        <div>
            <p>Call me Ishmael.....</p> 
        </div>
    </div>
</body>
</html>

4

คุณสามารถใช้-webkit-line-clampคุณสมบัติด้วยdivทรัพย์สินที่มี

-webkit-line-clamp: <integer>ซึ่งหมายถึงการตั้งค่าจำนวนบรรทัดสูงสุดก่อนที่จะตัดทอนเนื้อหาแล้วแสดงจุดไข่ปลา(…)ที่ท้ายบรรทัดสุดท้าย

div {
  width: 205px;
  height: 40px;
  background-color: gainsboro;
  overflow: hidden;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  
  /* <integer> values */
  -webkit-line-clamp: 2;
}
<div>This is a multi-lines text block, some lines inside the div, while some outside</div>


2
ไม่แน่ใจว่าทำไมมีใครบางคนลงคะแนนคำตอบนี้ การสนับสนุนเบราว์เซอร์ ณ เดือนมีนาคม 2563 ค่อนข้างดี - 95% caniuse.com/#search=line-clamp
Yulian

2

นี่เป็นวิธีการแก้ปัญหาวานิลลา JavaScript ที่คุณสามารถใช้ในการหยิก:

// @param 1 = element containing text to truncate
// @param 2 = the maximum number of lines to show
function limitLines(el, nLines) {
  var nHeight,
    el2 = el.cloneNode(true);
  // Create clone to determine line height
  el2.style.position = 'absolute';
  el2.style.top = '0';
  el2.style.width = '10%';
  el2.style.overflow = 'hidden';
  el2.style.visibility = 'hidden';
  el2.style.whiteSpace = 'nowrap';
  el.parentNode.appendChild(el2);
  nHeight = (el2.clientHeight+2)*nLines; // Add 2 pixels of slack
  // Clean up
  el.parentNode.removeChild(el2);
  el2 = null;
  // Truncate until desired nLines reached
  if (el.clientHeight > nHeight) {
    var i = 0,
      imax = nLines * 35;
    while (el.clientHeight > nHeight) {
      el.innerHTML = el.textContent.slice(0, -2) + '&hellip;';
      ++i;
      // Prevent infinite loop in "print" media query caused by
      // Bootstrap 3 CSS: a[href]:after { content:" (" attr(href) ")"; }
      if (i===imax) break;
    }
  }
}

limitLines(document.getElementById('target'), 7);
#test {
  width: 320px;
  font-size: 18px;
}
<div id="test">
  <p>Paragraph 1</p>
  <p id="target">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
  <p>Paragraph 3</p>
</div>

คุณสามารถเล่นกับมันใน codepen ด้านล่าง ลองเปลี่ยนขนาดตัวอักษรในแผง CSS และทำการแก้ไขเล็กน้อยในแผง HTML (เช่นเพิ่มพื้นที่พิเศษที่ใดที่หนึ่ง) เพื่ออัปเดตผลลัพธ์ โดยไม่คำนึงถึงขนาดตัวอักษรย่อหน้ากลางควรจะถูกปัดเศษเป็นจำนวนบรรทัดในพารามิเตอร์ที่สองที่ส่งผ่านไปยัง limitLines () เสมอ

Codepen: http://codepen.io/thdoan/pen/BoXbEK


2

แก้ไข: มาข้ามShaveซึ่งเป็นปลั๊กอิน JS ที่ทำการตัดทอนข้อความหลายบรรทัดตามความสูงสูงสุดที่กำหนดได้ดีจริงๆ มันใช้การค้นหาแบบไบนารี่เพื่อค้นหาจุดพักที่เหมาะสม คุ้มค่าที่จะตรวจสอบ


คำตอบเดิม:

ฉันต้องคิดหาวิธีแก้ปัญหาของ vanilla JS สำหรับปัญหานี้ ในกรณีที่ฉันทำงานฉันต้องใส่ชื่อผลิตภัณฑ์แบบยาวให้มีความกว้าง จำกัด และมากกว่าสองบรรทัด ถูกตัดทอนโดยจุดไข่ปลาหากจำเป็น

ฉันใช้คำตอบจากโพสต์ SO ต่างๆเพื่อทำสิ่งที่เหมาะสมกับความต้องการของฉัน กลยุทธ์มีดังนี้:

  1. คำนวณความกว้างอักขระเฉลี่ยของชุดตัวอักษรสำหรับขนาดตัวอักษรที่ต้องการ
  2. คำนวณความกว้างของคอนเทนเนอร์
  3. คำนวณจำนวนอักขระที่พอดีกับหนึ่งบรรทัดในคอนเทนเนอร์
  4. คำนวณจำนวนอักขระเพื่อตัดทอนสตริงให้เป็นไปตามจำนวนอักขระที่พอดีกับบรรทัดและจำนวนบรรทัดที่ข้อความควรถูกตัดคำ
  5. ตัดทอนข้อความอินพุตตามการคำนวณก่อนหน้า (แยกตัวประกอบสำหรับอักขระพิเศษที่เพิ่มโดยจุดไข่ปลา) และต่อท้าย "... " ต่อท้าย

ตัวอย่างโค้ด:

/**
 * Helper to get the average width of a character in px
 * NOTE: Ensure this is used only AFTER font files are loaded (after page load)
 * @param {DOM element} parentElement 
 * @param {string} fontSize 
 */
function getAverageCharacterWidth(parentElement, fontSize) {
    var textSample = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()";
    parentElement = parentElement || document.body;
    fontSize = fontSize || "1rem";
    var div = document.createElement('div');
    div.style.width = "auto";
    div.style.height = "auto";
    div.style.fontSize = fontSize;
    div.style.whiteSpace = "nowrap";
    div.style.position = "absolute";
    div.innerHTML = textSample;
    parentElement.appendChild(div);

    var pixels = Math.ceil((div.clientWidth + 1) / textSample.length);
    parentElement.removeChild(div);
    return pixels;
}

/**
 * Helper to truncate text to fit into a given width over a specified number of lines
 * @param {string} text Text to truncate
 * @param {string} oneChar Average width of one character in px
 * @param {number} pxWidth Width of the container (adjusted for padding)
 * @param {number} lineCount Number of lines to span over
 * @param {number} pad Adjust this to ensure optimum fit in containers. Use a negative value to Increase length of truncation, positive values to decrease it.
 */
function truncateTextForDisplay(text, oneChar, pxWidth, lineCount, pad) {
    var ellipsisPadding = isNaN(pad) ? 0 : pad;
    var charsPerLine = Math.floor(pxWidth / oneChar);
    var allowedCount = (charsPerLine * (lineCount)) - ellipsisPadding;
    return text.substr(0, allowedCount) + "...";
}


//SAMPLE USAGE:
var rawContainer = document.getElementById("raw");
var clipContainer1 = document.getElementById("clip-container-1");
var clipContainer2 = document.getElementById("clip-container-2");

//Get the text to be truncated
var text=rawContainer.innerHTML;

//Find the average width of a character
//Note: Ideally, call getAverageCharacterWidth only once and reuse the value for the same font and font size as this is an expensive DOM operation
var oneChar = getAverageCharacterWidth();

//Get the container width
var pxWidth = clipContainer1.clientWidth;

//Number of lines to span over
var lineCount = 2;

//Truncate without padding
clipContainer1.innerHTML = truncateTextForDisplay(text, oneChar, pxWidth, lineCount);

//Truncate with negative padding value to adjust for particular font and font size
clipContainer2.innerHTML = truncateTextForDisplay(text, oneChar, pxWidth, lineCount,-10);
.container{
  display: inline-block;
  width: 200px;
  overflow: hidden;
  height: auto;
  border: 1px dotted black;
  padding: 10px;
  }
<h4>Untruncated</h4>
<div id="raw" class="container">
This is super long text which needs to be clipped to the correct length with ellipsis spanning over two lines
</div>
<h4>Truncated</h4>
<div id="clip-container-1" class="container">
</div>
<h4>Truncated with Padding Tweak</h4>
<div id="clip-container-2" class="container">
</div>

PS:

  1. หากการตัดปลายต้องอยู่บนบรรทัดเดียวเท่านั้นวิธีการใช้ CSS ล้วนๆในการใช้ text-overflow: ellipsis คือ neater
  2. แบบอักษรที่ไม่มีความกว้างคงที่อาจทำให้การตัดทอนเกิดขึ้นเร็วเกินไปหรือช้าเกินไป (เนื่องจากอักขระที่แตกต่างกันมีความกว้างต่างกัน) การใช้พารามิเตอร์ pad ช่วยลดปัญหานี้ในบางกรณี แต่จะไม่เป็นข้อพิสูจน์ที่ผิดพลาด :)
  3. จะเพิ่มลิงก์และการอ้างอิงไปยังโพสต์ต้นฉบับหลังจากฉันได้รับแล็ปท็อปกลับมา (ต้องการประวัติ)

PPS: เพิ่งรู้ว่านี่คล้ายกับวิธีที่ @DanMan และ @ st.never แนะนำ ชำระเงินตัวอย่างโค้ดสำหรับตัวอย่างการนำไปใช้งาน


2

โซลูชัน JavaScript ที่ง่ายมาก Divs จะต้องมีสไตล์ fe:

.croppedTexts { 
  max-height: 32px;
  overflow: hidden;
}

และ JS:

var list = document.body.getElementsByClassName("croppedTexts");
for (var i = 0; i < list.length; i++) {
  cropTextToFit(list[i]);
}

function cropTextToFit (o) {
  var lastIndex;
  var txt = o.innerHTML;
  if (!o.title) o.title = txt;

  while (o.scrollHeight > o.clientHeight) {
    lastIndex = txt.lastIndexOf(" ");
    if (lastIndex == -1) return;
    txt = txt.substring(0, lastIndex);
    o.innerHTML = txt + "…";
  }
}

1

ไม่ใช่คำตอบที่ถูกต้องสำหรับคำถาม แต่ฉันเจอหน้านี้เมื่อพยายามทำสิ่งที่คล้ายกันมาก แต่ต้องการเพิ่มลิงก์ไปยัง "ดูเพิ่มเติม" แทนที่จะเป็นแค่จุดไข่ปลาตรงไปตรงมา นี่คือฟังก์ชั่น jQuery ที่จะเพิ่มลิงก์ "เพิ่มเติม" ไปยังข้อความที่ล้นคอนเทนเนอร์ โดยส่วนตัวฉันใช้สิ่งนี้กับ Bootstrap แต่แน่นอนว่ามันจะไม่ทำงาน

ตัวอย่างภาพหน้าจอเพิ่มเติม

วิธีใช้ใส่ข้อความของคุณในคอนเทนเนอร์ดังนี้:

<div class="more-less">
    <div class="more-block">
        <p>The long text goes in here</p>
    </div>
</div>

เมื่อเพิ่มฟังก์ชัน jQuery ต่อไปนี้ divs ใด ๆ ที่มีขนาดใหญ่กว่าค่าการปรับความสูงจะถูกตัดทอนและเพิ่มลิงค์ "เพิ่มเติม"

$(function(){
    var adjustheight = 60;
    var moreText = '+ More';
    var lessText = '- Less';
    $(".more-less .more-block").each(function(){
        if ($(this).height() > adjustheight){
            $(this).css('height', adjustheight).css('overflow', 'hidden');
            $(this).parent(".more-less").append
                ('<a style="cursor:pointer" class="adjust">' + moreText + '</a>');
        }
    });
    $(".adjust").click(function() {
        if ($(this).prev().css('overflow') == 'hidden')
        {
            $(this).prev().css('height', 'auto').css('overflow', 'visible');
            $(this).text(lessText);
        }
        else {
            $(this).prev().css('height', adjustheight).css('overflow', 'hidden');
            $(this).text(moreText);
        }
    });
});

ขึ้นอยู่กับสิ่งนี้ แต่อัปเดตแล้ว: http://shakenandstirredweb.com/240/jquery-moreless-text


<สูง> ฉันคิดว่าบางคนอาจลงคะแนนในที่นี้น่าจะเป็นเพราะมันไม่ใช่คำตอบที่แน่นอนสำหรับคำถาม อย่างไรก็ตามฉันหวังว่าบางคนจะพบว่ามีประโยชน์เพราะฉันไม่สามารถใช้ข้อมูลนี้ได้ทุกที่และนี่คือที่ที่ฉันจบการค้นหา
Andy Beverley

1

ปลั๊กอิน jQuery dotdotdot ที่กล่าวถึงใช้งานได้ดีกับ angular:

(function (angular) {
angular.module('app')
    .directive('appEllipsis', [
        "$log", "$timeout", function ($log, $timeout) {
            return {
                restrict: 'A',
                scope: false,
                link: function (scope, element, attrs) {

                    // let the angular data binding run first
                    $timeout(function() {
                        element.dotdotdot({
                            watch: "window"
                        });
                    });
                }
            }

        }
    ]);
})(window.angular);

มาร์กอัปที่สอดคล้องกันจะเป็น:

<p app-ellipsis>{{ selectedItem.Description }}</p>

1

การสาธิต JS บริสุทธิ์ (ไม่มี jQuery และ 'while' loop)

เมื่อฉันค้นหาวิธีแก้ปัญหาของจุดไข่ปลาหลายเส้นฉันรู้สึกประหลาดใจที่ไม่มีสิ่งใดที่ดีหากปราศจาก jQuery นอกจากนี้ยังมีวิธีแก้ปัญหาบางอย่างที่ใช้ 'ขณะที่' ลูป แต่ฉันคิดว่ามันไม่ได้มีประสิทธิภาพและอันตรายเนื่องจากความเป็นไปได้ที่จะเข้าสู่วงวนไม่สิ้นสุด ดังนั้นฉันจึงเขียนรหัสนี้:

function ellipsizeTextBox(el) {
  if (el.scrollHeight <= el.offsetHeight) {
    return;
  }

  let wordArray = el.innerHTML.split(' ');
  const wordsLength = wordArray.length;
  let activeWord;
  let activePhrase;
  let isEllipsed = false;

  for (let i = 0; i < wordsLength; i++) {
    if (el.scrollHeight > el.offsetHeight) {
      activeWord = wordArray.pop();
      el.innerHTML = activePhrase = wordArray.join(' ');
    } else {
      break;
    }
  }

  let charsArray = activeWord.split('');
  const charsLength = charsArray.length;

  for (let i = 0; i < charsLength; i++) {
    if (el.scrollHeight > el.offsetHeight) {
      charsArray.pop();
      el.innerHTML = activePhrase + ' ' + charsArray.join('')  + '...';
      isEllipsed = true;
    } else {
      break;
    }
  }

  if (!isEllipsed) {
    activePhrase = el.innerHTML;

    let phraseArr = activePhrase.split('');
    phraseArr = phraseArr.slice(0, phraseArr.length - 3)
    el.innerHTML = phraseArr.join('') + '...';
  }
}

let el = document.getElementById('ellipsed');

ellipsizeTextBox(el);

1

อาจจะค่อนข้างช้า แต่ใช้ SCSS คุณสามารถประกาศฟังก์ชั่นที่ชอบ:

@mixin clamp-text($lines, $line-height) {
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: $lines;
  line-height: $line-height;
  max-height: unquote('#{$line-height*$lines}em');

  @-moz-document url-prefix() {
    position: relative;
    height: unquote('#{$line-height*$lines}em');

    &::after {
      content: '';
      text-align: right;
      position: absolute;
      bottom: 0;
      right: 0;
      width: 30%;
      height: unquote('#{$line-height}em');
      background: linear-gradient(
        to right,
        rgba(255, 255, 255, 0),
        rgba(255, 255, 255, 1) 50%
      );
    }
  }
}

และใช้มันเช่น:

.foo {
    @include clamp-text(1, 1.4);
}

ซึ่งจะตัดทอนข้อความให้เป็นหนึ่งบรรทัดและรู้ว่าเป็นความสูงบรรทัดที่ 1.4 ผลลัพธ์ที่คาดหวังคือโครเมี่ยมที่จะแสดงผล...ที่ส่วนท้ายและ FF ที่มีสีจาง ๆ ในตอนท้าย

Firefox

ป้อนคำอธิบายรูปภาพที่นี่

โครเมียม

ป้อนคำอธิบายรูปภาพที่นี่


1

พบโซลูชันCSS-onlyสั้น ๆ นี้ในคำตอบของ Adrien Be :

.line-clamp {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical; 
  overflow: hidden; 
}

มีนาคม 2020 การสนับสนุนเบราว์เซอร์เป็น95.3%ไม่ได้รับการสนับสนุนใน IE และ Opera Mini ใช้งานได้กับ Chrome, Safari, Firefox และ Edge


0

คุณอาจไม่สามารถทำได้ (ในปัจจุบัน?) หากไม่มีแบบอักษรที่มีความกว้างคงที่เช่น Courier ด้วยตัวอักษรที่มีความกว้างคงที่ตัวอักษรทุกตัวใช้พื้นที่แนวนอนเดียวกันดังนั้นคุณอาจนับตัวอักษรและทวีคูณผลลัพธ์ด้วยขนาดตัวอักษรปัจจุบันเป็น ems หรือ exs จากนั้นคุณจะต้องทดสอบจำนวนตัวอักษรที่พอดีกับหนึ่งบรรทัดแล้วแยกมันออก

อีกทางเลือกหนึ่งสำหรับแบบอักษรที่ไม่ใช่แบบตายตัวคุณอาจสร้างการแมปสำหรับตัวอักษรที่เป็นไปได้ทั้งหมด (เช่น i = 2px, m = 5px) จากนั้นทำการคำนวณ แม้ว่าการทำงานน่าเกลียดมากมาย


0

หากต้องการขยายโซลูชันของ @ DanMan: ในกรณีที่ใช้แบบอักษรที่มีความกว้างผันแปรได้คุณสามารถใช้ความกว้างของแบบอักษรโดยเฉลี่ยได้ ปัญหานี้มีสองปัญหา: 1) ข้อความที่มี W มากเกินควรและ 2) ข้อความที่มีมากเกินไปที่ฉันจะถูกตัดทอนก่อนหน้านี้

หรือคุณอาจใช้กรณีที่เลวร้ายที่สุดและใช้ความกว้างของตัวอักษร "W" (ซึ่งฉันเชื่อว่ากว้างที่สุด) สิ่งนี้จะลบปัญหา 1 ด้านบน แต่ทวีความรุนแรงมากขึ้นปัญหา 2

วิธีที่แตกต่างอาจเป็น: ปล่อยให้overflow: clipdiv และเพิ่มส่วนจุดไข่ปลา (อาจเป็น div หรือรูปภาพอื่น)float: right; position: relative; bottom: 0px; (ยังไม่ทดลอง) เคล็ดลับคือการทำให้ภาพปรากฏเหนือส่วนท้ายของข้อความ

คุณสามารถแสดงเฉพาะภาพเมื่อคุณรู้ว่ากำลังจะล้น (เช่นหลังจากตัวอักษรประมาณ 100 ตัว)


คือoverflow: clipอะไร และคุณคาดหวังอะไรกับ CSS ที่floatต้องทำ?
kapa

0

ด้วยรหัสนี้ไม่จำเป็นสำหรับ div wrapper พิเศษหากองค์ประกอบที่มีความสูงถูก จำกัด ด้วยรูปแบบความสูงสูงสุด

// Shorten texts in overflowed paragraphs to emulate Operas text-overflow: -o-ellipsis-lastline
$('.ellipsis-lastline').each(function(i, e) {
    var $e = $(e), original_content = $e.text();
    while (e.scrollHeight > e.clientHeight)
        $e.text($e.text().replace(/\W*\w+\W*$/, '…'));
    $e.attr('data-original-content', original_content);
});

นอกจากนี้ยังบันทึกข้อความต้นฉบับในแอททริบิวต์ข้อมูลที่สามารถแสดงผลได้โดยใช้สไตล์เท่านั้นเช่น วางเมาส์เหนือ:

.ellipsis-lastline {
    max-height: 5em;
}
.ellipsis-lastline:before {
    content: attr(data-original-content);
    position: absolute;
    display: none;
}
.ellipsis-lastline:hover:before {
    display: block;
}

1
นั่นมักจะวนซ้ำไม่สิ้นสุด
Atadj

0

ในสถานการณ์ของฉันฉันไม่สามารถทำงานใด ๆ ของฟังก์ชั่นดังกล่าวข้างต้นและฉันยังต้องบอกฟังก์ชั่นจำนวนบรรทัดที่จะแสดงโดยไม่คำนึงถึงขนาดตัวอักษรหรือขนาดคอนเทนเนอร์

ผมตามแก้ปัญหาของฉันกับการใช้งานของCanvas.measureTextวิธี (whic เป็นHTML5คุณลักษณะ) ตามที่อธิบายไว้ที่นี่โดยDomiจึงไม่สมบูรณ์ข้ามเบราว์เซอร์

คุณสามารถดูวิธีการทำงานของซอนี้

นี่คือรหัส:

var processTexts = function processTexts($dom) {
    var canvas = processTexts .canvas || (processTexts .canvas = document.createElement("canvas"));

    $dom.find('.block-with-ellipsis').each(function (idx, ctrl) {
        var currentLineAdded = false;
        var $this = $(ctrl);

        var font = $this.css('font-family').split(",")[0]; //This worked for me so far, but it is not always so easy.
        var fontWeight = $(this).css('font-weight');
        var fontSize = $(this).css('font-size');
        var fullFont = fontWeight + " " + fontSize + " " + font;
        // re-use canvas object for better performance
        var context = canvas.getContext("2d");
        context.font = fullFont;

        var widthOfContainer = $this.width();
        var text = $.trim(ctrl.innerHTML);
        var words = text.split(" ");
        var lines = [];
        //Number of lines to span over, this could be calculated/obtained some other way.
        var lineCount = $this.data('line-count');

        var currentLine = words[0];
        var processing = "";

        var isProcessing = true;
        var metrics = context.measureText(text);
        var processingWidth = metrics.width;
        if (processingWidth > widthOfContainer) {
            for (var i = 1; i < words.length && isProcessing; i++) {
                currentLineAdded = false;
                processing = currentLine + " " + words[i];
                metrics = context.measureText(processing);
                processingWidth = metrics.width;
                if (processingWidth <= widthOfContainer) {
                    currentLine = processing;
                } else {
                    if (lines.length < lineCount - 1) {
                        lines.push(currentLine);
                        currentLine = words[i];
                        currentLineAdded = true;
                    } else {
                        processing = currentLine + "...";
                        metrics = context.measureText(processing);
                        processingWidth = metrics.width;
                        if (processingWidth <= widthOfContainer) {
                            currentLine = processing;
                        } else {
                            currentLine = currentLine.slice(0, -3) + "...";
                        }
                        lines.push(currentLine);
                        isProcessing = false;
                        currentLineAdded = true;
                    }
                }
            }
            if (!currentLineAdded)
                lines.push(currentLine);
            ctrl.innerHTML = lines.join(" ");
        }
    });
};

(function () {
    $(document).ready(function () {
        processTexts($(document));
    });
})();

และ HTML ที่ใช้มันจะเป็นเช่นนี้:

<div class="block-with-ellipsis" data-line-count="2">
    VERY LONG TEXT THAT I WANT TO BREAK IN LINES. VERY LONG TEXT THAT I WANT TO BREAK IN LINES.
</div>

รหัสในการรับฟอนต์ตระกูลนั้นค่อนข้างง่ายและในกรณีของฉันใช้งานได้ แต่สำหรับสถานการณ์ที่ซับซ้อนมากขึ้นคุณอาจจำเป็นต้องใช้บางอย่างตามบรรทัดเหล่านี้เส้นเหล่านี้

ในกรณีของฉันฉันกำลังบอกฟังก์ชั่นว่าต้องใช้กี่บรรทัด แต่คุณสามารถคำนวณจำนวนบรรทัดที่จะแสดงตามขนาดคอนเทนเนอร์และแบบอักษร


0

ฉันได้สร้างเวอร์ชันที่ทำให้ html ไม่เป็นอันตราย ตัวอย่าง jsfiddle

jQuery

function shorten_text_to_parent_size(text_elem) {
  textContainerHeight = text_elem.parent().height();


  while (text_elem.outerHeight(true) > textContainerHeight) {
    text_elem.html(function (index, text) {
      return text.replace(/(?!(<[^>]*>))\W*\s(\S)*$/, '...');
    });

  }
}

$('.ellipsis_multiline').each(function () {
  shorten_text_to_parent_size($(this))
});

CSS

.ellipsis_multiline_box {
  position: relative;
  overflow-y: hidden;
  text-overflow: ellipsis;
}

ตัวอย่าง jsfiddle


0

ฉันเขียนองค์ประกอบเชิงมุมที่แก้ปัญหาได้ มันแยกข้อความที่กำหนดลงในองค์ประกอบช่วง หลังจากเรนเดอร์แล้วมันจะลบองค์ประกอบที่โอเวอร์โฟลว์ทั้งหมดและวางจุดไข่ปลาไว้ทางขวามือหลังจากองค์ประกอบที่มองเห็นได้สุดท้าย

ตัวอย่างการใช้งาน:

<app-text-overflow-ellipsis [text]="someText" style="max-height: 50px"></app-text-overflow-ellipsis>

Stackblitz demo: https://stackblitz.com/edit/angular-wfdqtd

ส่วนประกอบ:

import {
  ChangeDetectionStrategy,
  ChangeDetectorRef,
  Component,
  ElementRef, HostListener,
  Input,
  OnChanges,
  ViewChild
} from '@angular/core';

@Component({
  changeDetection: ChangeDetectionStrategy.OnPush,
  selector: 'app-text-overflow-ellipsis',
  template: `
    <span *ngFor="let word of words; let i = index" [innerHTML]="word + (!endsWithHyphen(i) ? ' ' : '')"></span>
    <span #ellipsis [hidden]="!showEllipsis && !initializing" [class.initializing]="initializing" [innerHTML]="'...' + (initializing ? '&nbsp;' : '')"></span>
  `,
  styles: [`
    :host {
      display: block; 
      position: relative;
    }
    .initializing {
      opacity: 0;
    }
  `
  ]
})

export class TextOverflowEllipsisComponent implements OnChanges {
  @Input()
  text: string;

  showEllipsis: boolean;
  initializing: boolean;

  words: string[];

  @ViewChild('ellipsis')
  ellipsisElement: ElementRef;

  constructor(private element: ElementRef, private cdRef: ChangeDetectorRef) {}

  ngOnChanges(){
    this.init();
  }

  @HostListener('window:resize')
  init(){
    // add space after hyphens
    let text = this.text.replace(/-/g, '- ') ;

    this.words = text.split(' ');
    this.initializing = true;
    this.showEllipsis = false;
    this.cdRef.detectChanges();

    setTimeout(() => {
      this.initializing = false;
      let containerElement = this.element.nativeElement;
      let containerWidth = containerElement.clientWidth;
      let wordElements = (<HTMLElement[]>Array.from(containerElement.childNodes)).filter((element) =>
        element.getBoundingClientRect && element !== this.ellipsisElement.nativeElement
      );
      let lines = this.getLines(wordElements, containerWidth);
      let indexOfLastLine = lines.length - 1;
      let lineHeight = this.deductLineHeight(lines);
      if (!lineHeight) {
        return;
      }
      let indexOfLastVisibleLine = Math.floor(containerElement.clientHeight / lineHeight) - 1;

      if (indexOfLastVisibleLine < indexOfLastLine) {

        // remove overflowing lines
        for (let i = indexOfLastLine; i > indexOfLastVisibleLine; i--) {
          for (let j = 0; j < lines[i].length; j++) {
            this.words.splice(-1, 1);
          }
        }

        // make ellipsis fit into last visible line
        let lastVisibleLine = lines[indexOfLastVisibleLine];
        let indexOfLastWord = lastVisibleLine.length - 1;
        let lastVisibleLineWidth = lastVisibleLine.map(
          (element) => element.getBoundingClientRect().width
        ).reduce(
          (width, sum) => width + sum, 0
        );
        let ellipsisWidth = this.ellipsisElement.nativeElement.getBoundingClientRect().width;
        for (let i = indexOfLastWord; lastVisibleLineWidth + ellipsisWidth >= containerWidth; i--) {
          let wordWidth = lastVisibleLine[i].getBoundingClientRect().width;
          lastVisibleLineWidth -= wordWidth;
          this.words.splice(-1, 1);
        }


        this.showEllipsis = true;
      }
      this.cdRef.detectChanges();

      // delay is to prevent from font loading issues
    }, 1000);

  }

  deductLineHeight(lines: HTMLElement[][]): number {
    try {
      let rect0 = lines[0][0].getBoundingClientRect();
      let y0 = rect0['y'] || rect0['top'] || 0;
      let rect1 = lines[1][0].getBoundingClientRect();
      let y1 = rect1['y'] || rect1['top'] || 0;
      let lineHeight = y1 - y0;
      if (lineHeight > 0){
        return lineHeight;
      }
    } catch (e) {}

    return null;
  }

  getLines(nodes: HTMLElement[], clientWidth: number): HTMLElement[][] {
    let lines = [];
    let currentLine = [];
    let currentLineWidth = 0;

    nodes.forEach((node) => {
      if (!node.getBoundingClientRect){
        return;
      }

      let nodeWidth = node.getBoundingClientRect().width;
      if (currentLineWidth + nodeWidth > clientWidth){
        lines.push(currentLine);
        currentLine = [];
        currentLineWidth = 0;
      }
      currentLine.push(node);
      currentLineWidth += nodeWidth;
    });
    lines.push(currentLine);

    return lines;
  }

  endsWithHyphen(index: number): boolean {
    let length = this.words[index].length;
    return this.words[index][length - 1] === '-' && this.words[index + 1] && this.words[index + 1][0];
  }
}

0

ที่นี่ฉันสร้างอีกไลบรารีด้วยอัลกอริทึมที่เร็วขึ้น โปรดตรวจสอบ:

https://github.com/i-ahmed-biz/fast-ellipsis

วิธีการติดตั้งโดยใช้ bower:

bower install fast-ellipsis

ในการติดตั้งโดยใช้ npm:

npm install fast-ellipsis 

หวังว่าคุณจะสนุก!


-2

ไม่แน่ใจว่านี่คือสิ่งที่คุณกำลังมองหาหรือไม่มันใช้ความสูงขั้นต่ำแทนความสูง

    <div id="content" style="min-height:10px;width:190px;background:lightblue;">
    <?php 
        function truncate($text,$numb) {
            // source: www.kigoobe.com, please keep this if you are using the function
            $text = html_entity_decode($text, ENT_QUOTES);
            if (strlen($text) > $numb) {
                $text = substr($text, 0, $numb);
                $etc = "..."; 
                $text = $text.$etc;
            } 
            $text = htmlentities($text, ENT_QUOTES);
            return $text;
        }
        echo truncate("this is a multi-lines text block, some lines inside the div, while some outside", 63);
    ?>
    </div>

4
ปัญหาคือหมายเลข 63 ในรหัสของคุณหากทราบหมายเลขแล้วทุกอย่างกลายเป็นเรื่องง่ายฟังก์ชั่นที่ถูกตัดทอนจะทำงานเช่นเดียวกับรหัสของคุณ อย่างไรก็ตามจะรู้จำนวนได้อย่างไร กล่าวอีกนัยหนึ่งจะทราบได้อย่างไรว่าข้อความจะถูกแบ่งบรรทัดที่ใด ถ้าคำถามนี้สามารถตอบได้แล้วปัญหาจะสามารถแก้ไขได้เพียงแค่ในตรรกะของ "1 คำนวณจำนวนนั้น 2 ตัด"
เอ็ดเวิร์ด

-3

func ง่ายมากจะทำ

Directive:

  $scope.truncateAlbumName = function (name) {
    if (name.length > 36) {
      return name.slice(0, 34) + "..";
    } else {
      return name;
    }
  };

ดู:

<#p>{{truncateAlbumName(album.name)}}<#/p>

3
ดังที่เราได้พูดคุยกันแล้วภายใต้คำตอบอื่น ๆ ปัญหาในรหัสของคุณคือหมายเลข 36 นอกจากการทำให้โค้ดของคุณเฉพาะกับความกว้างของคอนเทนเนอร์ที่แน่นอนมันก็ไม่ถูกต้อง: ด้วยแบบอักษรที่ไม่ใช่ความกว้างคงที่ . ดูiiiiiiiiiivs MMMMMMMMMM(ด้วยตัวอักษรปัจจุบันที่มองไม่เห็นแม้ว่า: D)
kapa
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.