วิธีการจัดแนวข้อความทั้งหมดใน CSS ในแนวตั้ง?


12

ปัญหาน่าจะเป็นที่ตัวอักษรบางอย่างเช่นg, y, qและอื่น ๆ ที่มีหางที่เนินเขาลงไม่อนุญาตให้แนวตั้งตรงกลาง aนี่คือภาพที่จะแสดงปัญหา

ตัวละครในกล่องสีเขียวนั้นสมบูรณ์แบบเพราะไม่มีหางเลย ผู้ที่อยู่ในกล่องสีแดงแสดงให้เห็นถึงปัญหา

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

นี่คือไวโอลินที่แสดงให้เห็นถึงปัญหาที่เกิดขึ้นในเต็มรูปแบบ

.avatar {
    border-radius: 50%;
    display: inline-block;
    text-align: center;
    width: 125px;
    height: 125px;
    font-size: 60px;
    background-color: rgb(81, 75, 93);
    font-family: "Segoe UI";
    margin-bottom: 10px;
}

.character {
    position: relative;
    top: 50%;
    transform: translateY(-50%);
    line-height: 100%;
    color: #fff;
}
<div class="avatar">
  <div class="character">W</div>
</div>

<div class="avatar">
  <div class="character">y</div>
</div>


1
นี่เป็นคำถามที่น่าสนใจ คำตอบอาจอยู่ที่นี่: iamvdo.me/en/blog/…
dwjohnston

2
ในกรณีนี้คุณจำเป็นต้องกำหนดสิ่งที่เป็นศูนย์ สำหรับผมYเป็นศูนย์กลางจริงและอาจจะไม่ อย่าพูดเมื่อเรามีครอบครัวฟอนต์ที่แตกต่างกันการจัดตำแหน่งจะแย่ลงเรื่อย ๆ
Temani Afif

1
นั่นเป็นวิธีการทำงานของตัวอักษร พวกเขาถูกจัดตำแหน่งเนื่องจากvในyและoส่วนหนึ่งในgอยู่บนบรรทัดเดียวกันกับจุดต่ำสุดสำหรับตัวพิมพ์ใหญ่ ด้วยตรรกะของคุณÅ, Ä, Öจะได้รับการจัดตำแหน่งเหมือนกับ A และ O แต่ไม่สามารถทำได้ หากคุณต้องการทำอะไรเป็นพิเศษเกี่ยวกับเรื่องนี้คุณต้องใช้จาวาสคริปต์เพื่อตรวจสอบว่าเป็นตัวอักษรตัวเล็กหรือไม่
Rickard Elimää

1
ฉันอยากรู้ถ้ามีคำตอบที่เป็นประโยชน์ที่นี่ ปัญหาดูเหมือนจะเป็นที่แท้จริงเหล่านี้เป็นศูนย์กลาง กล่าวคือ บอกว่าคุณสามารถเลื่อน y และ g ขึ้นมาได้ถ้าคุณมีตัวพิมพ์เล็ก a? ควรแสดงผลอย่างไร
dwjohnston

2
เปิดแบบอักษรของคุณในตัวแก้ไขแบบอักษรใด ๆ แก้ไขตัวละครทุกตัวจนคุณมีความสุขอยู่กับสิ่งที่คุณเห็นเป็น"ศูนย์กลาง" บันทึกและใช้เป็นฟอนต์ตระกูลใหม่ของคุณ ควรใช้เวลาไม่เกิน 15 นาที ฉันไม่เห็นวิธีที่มีเหตุผลอื่นนอกจาก SVG หรือกลอุบายอื่น ๆ โดยใช้ Canvas & co แต่ฉันจะคิดถึงคำถามนี้
Roko C. Buljan

คำตอบ:


4

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

รหัสไม่ได้รับการปรับปรุง แต่เน้นแนวคิดหลัก:

UPDATE

นี่คือการเพิ่มประสิทธิภาพแรกของรหัส:

var elems = document.querySelectorAll(".avatar");
var k = 0;

for (var i = 0; i < elems.length; i++) {
  domtoimage.toPixelData(elems[i])
    .then(function(im) {
     var l = im.length;
      /* Search for the top limit */
      var t = 0;
      for (var j = 0; j < l; j+=4) {
          if (im[j+1] == 255) { /* Since we know the colors, we can only test the G composant */
            t = Math.ceil((j/4)/125);
            break;
          }
      }
      /* Search the bottom limit*/
      var b = 0;
      for (var j = l - 1; j >= 0; j-=4) {
          if (im[j+1] == 255) {
            b = 125 - Math.ceil((j/4)/125);
            break;
          }
      }
      /* get the difference and apply a translation*/
      elems[k].querySelector('.character').style.transform = "translateY(" + (b - t)/2 + "px)";
      k++;
    });
}
.avatar {
  border-radius: 50%;
  display: inline-flex;
  vertical-align:top;
  justify-content: center;
  align-items: center;
  width: 125px;
  height: 125px;
  font-size: 60px;
  background: 
    linear-gradient(red,red) center/100% 1px no-repeat,
    rgb(81, 75, 93);
  font-family: "Segoe UI";
  margin-bottom: 10px;
}

.character {
  color: #fff;
}
<script type="text/javascript" src="https://css-challenges.com/wp-content/themes/ronneby_child/js/dom-to-image.js"></script>
<div class="avatar">
  <div class="character">W</div>
</div>

<div class="avatar">
  <div class="character">y</div>
</div>

<div class="avatar">
  <div class="character" style="font-size:35px">a</div>
</div>

<div class="avatar">
  <div class="character" style="font-size:25px">2</div>
</div>
<div class="avatar">
  <div class="character">o</div>
</div>
<div class="avatar">
  <div class="character">|</div>
</div>
<div class="avatar">
  <div class="character">@</div>
</div>
<div class="avatar">
  <div class="character">Â</div>
</div>

<div class="avatar">
  <div class="character" style="font-family:arial">Q</div>
</div>
<div class="avatar">
  <div class="character">~</div>
</div>
<div class="avatar">
  <div class="character">8</div>
</div>

<div class="avatar">
  <div class="character">ä</div>
</div>
<div class="avatar">
  <div class="character">ç</div>
</div>

<div class="avatar">
  <div class="character">$</div>
</div>

<div class="avatar">
  <div class="character">></div>
</div>
<div class="avatar">
  <div class="character">%</div>
</div>

ฉันใช้ปลั๊กอินdom-to-imageสำหรับสิ่งนี้


ไรวิ่งช้า แต่นี่เป็นโซลูชั่นแรกที่ทำงานอย่างต่อเนื่องจนถึงตอนนี้ (ด้วยข้อแม้ที่เป็นศูนย์กลางทางเทคนิคÂดูแปลก ๆ )
Brilliand

@ Brilliand ฉันใช้Âเพื่อแสดงให้เห็นอย่างชัดเจนว่าการอยู่ตรงกลางของเขาไม่เหมาะอย่างยิ่งเมื่อฉันแสดงความคิดเห็นในคำตอบของเขา;) เขาอาจจะเปลี่ยนใจหลังจากที่ได้เห็นสิ่งนี้และยอมรับวิธีการทำงานแบบอักษร
Temani Afif

มันดูดีทีเดียว ฉันคิดว่าฉันจะใช้สิ่งนี้หากฉันสามารถทำให้มีประสิทธิภาพมากขึ้น ดูเหมือนว่าในปัจจุบันจะค่อนข้างช้า
Chron Bag

@ChronBag ใช่คุณสามารถทำงานกับรหัสและเพิ่มประสิทธิภาพมันมีห้องสำหรับสิ่งนี้ ฉันไม่ได้ทำเพราะมันใช้เวลามากและไม่ใช่จุดประสงค์ของคำถาม ฉันต้องการที่จะมุ่งเน้นไปที่ความคิดหลัก อาจจะทำในภายหลังตามวิธี
Temani Afif

@ChronBag เพิ่มการเพิ่มประสิทธิภาพเร็วขึ้นเล็กน้อยฉันเดา
Temani Afif

1

อาจมีคำตอบที่ดีกว่า แต่ดูเหมือนว่าวิธีเดียวที่จะใช้สไตล์ที่แตกต่างด้วยตนเองขึ้นอยู่กับว่าเป็นหนึ่งใน:

  • ตัวพิมพ์ใหญ่
  • ตัวพิมพ์เล็กด้วยหาง
  • ตัวพิมพ์เล็กที่มีก้าน
  • ตัวพิมพ์เล็กด้วยไม่ใช่

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

โปรดทราบด้วยว่าโซลูชันนี้จะไม่ทำงานสำหรับการสนับสนุนหลายภาษา - เนื่องจากคุณจะต้องกำหนดหมวดหมู่ที่อักขระทุกตัวเหมาะกับชุดอักขระที่แตกต่างกันหลายสิบชุด

const letters = ['a', 'b', 'y', 'X', 'c', 'y', 'A', 'B', 'Y']; 

function getAdditionalClass(char){
    //To do - fill arrays with the rest of the appropriate letters
    if (['y', 'g'].includes(char)) {
        return "tail"; 
    }
    if (['b', 'd'].includes(char)) {
        return "stalk"; 
    }
    
    if (['a', 'c'].includes(char)) {
        return "small"; 
    }
    
    return "capital"; 
}

letters.forEach(v => {
  const avatar = document.createElement("div"); 
  avatar.className = "avatar"; 
  const character = document.createElement("div");
  character.textContent = v; 
  character.className = `character ${getAdditionalClass(v)}`; 
  
  avatar.appendChild(character); 
  
  const root = document.getElementById("root"); 
  
  root.appendChild(avatar); 
  
});
.avatar {
    border-radius: 50%;
    display: block;
    text-align: center;
    width: 125px;
    height: 125px;
    font-size: 60px;
    background-color: rgb(81, 75, 93);
    font-family: "Segoe UI";
    margin-bottom: 10px;
}

.character {
    position: relative;
    transform: translateY(-50%);
    line-height: 100%;
    color: #fff;
}


.small {
    top: 45%; 
}

.stalk {
    top: 50%;
}

.tail {
    top: 41%;
}

.capital {
    top: 50%;
}

#root {
    display: flex; 
    flex-flow: row wrap; 
}
<div id = "root">

</div>


ฉันหวังว่าจะหลีกเลี่ยงสิ่งนี้ แต่มันอาจเป็นทางออกเดียว ถ้าไม่มีอะไรมาฉันจะใช้มัน ขอบคุณ
Chron Bag

2
หากตัวอักษรสามารถเป็นตัวอักษร unicode ใด ๆ (จากตัวอักษรใด ๆ ) แล้วสิ่งนี้จะกลายเป็นใช้ไม่ได้
Brilliand

คุณลืมÂËและâë
Temani Afif

ใช่แล้วจุดดี @Brilliand ผู้ใช้ของฉันจะสามารถใช้ข้อความ unicode ใด ๆ สำหรับชื่อที่แสดงดังนั้นโซลูชันนี้จึงมีความเปราะมากยิ่งขึ้น
Chron Bag

0

นี่เป็นสถานการณ์ที่ยุ่งยาก!

จากสิ่งที่ผมสามารถบอกได้นี้จะเป็นเรื่องยากมากที่สุดเพื่อให้สามารถปรับขนาดได้โดยกำเนิด (เช่น%, vwหรือvhค่าแทนpxหรือem) หากคุณต้องการทำให้สิ่งนี้ดูสวยบนมือถือหรือแท็บเล็ตโปรดพิจารณาใช้โซลูชันของฉันด้วย@mediaจุดพัก

วิธีการแก้ปัญหาของฉันตรวจพบว่าเป็นองค์ประกอบตัวพิมพ์เล็กด้วยหางและเพิ่มคลาสเพื่อชดเชยความสูงเพื่อชดเชยหาง

ในการทดสอบของฉันก็ไม่ปรากฏว่ารถขนใด ๆ เพิ่มเติมที่จำเป็นสำหรับทุนตัวอักษรหรือกรณีที่ต่ำกว่าตัวอักษรโดยไม่ต้องหาง อย่าลังเลที่จะแก้ไขฉันหากฉันผิด

มีJSFiddleหากคุณต้องการยุ่งและเปลี่ยน / ทดสอบโซลูชันนี้

var circles = document.getElementsByClassName('circle');
var tails = ['q', 'y', 'p', 'g', 'j'] ;

Array.from(circles).forEach(render);
  
function render(element) { 		
    if(element.innerText == element.innerText.toLowerCase() &&
    	tails.includes(element.innerText)) {
    	element.className += " scale";
    }
}
.circle {
  height: 150px;
  width: 150px;
  background-color: #bbb;
  border-radius: 50%;
  display: inline-block;
  text-align: center;
  vertical-align: middle;
  line-height: 150px;
  font-size: 50px;
}

.scale {
  line-height: 135px;
}
<div>
  <div class="circle">W</div>
  <div class="circle">X</div>
</div>
<div>
  <div class="circle">y</div>
  <div class="circle">t</div>
</div>

แจ้งให้เราทราบความคิดของคุณและหากฉันไม่ได้รับอะไร มันคงเจ๋งที่ได้คำตอบสุดท้ายสำหรับเรื่องนี้เพราะฉันมีปัญหาที่คล้ายกันในอดีตที่ผ่านมา!


สิ่งนี้ดูเหมือนจะคล้ายกับวิธีแก้ปัญหาของ dwjohnston และมีข้อผิดพลาดเหมือนกับเขา อย่างไรก็ตามมันก็เป็นที่นิยมและฉันอาจจะจบลงด้วยการมีบางสิ่งตามสายเหล่านี้หากไม่มีสิ่งใดในอุดมคติมากขึ้น
Chron Bag

ฉันคิดว่าเป็นวิธีสุดท้ายคุณสามารถลงไปตามเส้นทางของการนับพิกเซล - ตามที่เห็นที่นี่โดยที่คุณจะตรวจสอบว่ามันมีความสูงจริงเป็นพิกเซลแล้วจึงใช้การชดเชยที่เหมาะสม
EGC

1
ใช่ฉันพูดถึงความคิดนั้นในความคิดเห็นต่อ OP อาจเป็นวิธีที่จะไป
Chron Bag

ขออภัยที่ต้องแจ้งความคิดของคุณอีกครั้ง .. มีความคิดเห็นมากเกินไป
EGC

-1

คุณอาจต้องใช้เฮลเพอร์คลาสสำหรับสิ่งนี้เพื่อให้คุณสามารถแปลอักษรตัวพิมพ์เล็กได้มากกว่าตัวพิมพ์ใหญ่ สคริปต์อย่างง่ายสามารถทำให้คลาสตัวช่วยเหล่านี้เปิดได้โดยอัตโนมัติ

หวังว่านี่จะช่วยแก้ปัญหาให้คุณ :)

.avatar {
    border-radius: 50%;
    display: block;
    text-align: center;
    width: 125px;
    height: 125px;
    font-size: 60px;
    background-color: rgb(81, 75, 93);
    font-family: "Segoe UI";
    margin-bottom: 10px;
}

.character {
    position: relative;
    top: 50%;
    line-height: 100%;
    color: #fff;
}
.character-lowercase {
  transform: translateY(-60%);
}
.character-capital {
  transform: translateY(-50%);
}
<div class="avatar">
  <div class="character character-capital">W</div>
</div>

<div class="avatar">
  <div class="character character-lowercase">y</div>
</div>


คุณyไม่ได้อยู่ตรงกลาง Tweek มากขึ้น!
Roko C. Buljan

ฉันไม่ทราบล่วงหน้าด้วยว่าตัวอักษรจะเป็นอย่างไร
Chron Bag

ผมเข้าใจว่า แต่สคริปต์ที่ตรวจสอบว่าตัวอักษรเป็นพิมพ์ใหญ่หรือตัวพิมพ์เล็กและทำให้ helperclass ใน HTML ขึ้นอยู่กับการที่จะแก้ปัญหาที่ง่าย :)
Ragna Roaldset

@RagnaRoaldset ฉันคิดว่าเขาไม่ได้หมายถึงตัวพิมพ์ใหญ่หรือตัวพิมพ์เล็ก เขาหมายถึงตัวละครตัวเล็ก แต่มีลักษณะที่แตกต่างกัน เปรียบเทียบoและyคุณจะได้รับ อักขระที่มีก้อยจะสร้างปัญหาตั้งแต่แรก (กล่าวถึงในโพสต์)
แอนนา

1
คุณสามารถสร้างอาร์เรย์สำหรับตัวอักษรทั้งหมดที่มีก้อยและวนรอบมันเพื่อตรวจสอบว่าตัวอักษรในการแข่งขัน div ก่อนที่จะใช้คลาส :) แต่ฉันเข้าใจแล้วลองใช้วิธีแก้ปัญหา :) หวังว่าจะมีใครมาด้วย it :)
Ragna Roaldset
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.