Làm cách nào để sắp xếp theo chiều dọc tất cả văn bản trong CSS?


12

Vấn đề này dường như là chữ nhất định như g, y, q, vv mà có một cái đuôi mà dốc xuống, không cho phép định tâm dọc. Đây là một hình ảnh để giới thiệu vấn đề một.

Các nhân vật trong hộp màu xanh lá cây về cơ bản là hoàn hảo, vì chúng không có đuôi đi xuống. Những người trong hộp màu đỏ chứng minh vấn đề.

Tôi muốn tất cả các nhân vật được tập trung hoàn hảo theo chiều dọc. Trong ảnh, các ký tự có đuôi hướng xuống không được căn giữa theo chiều dọc. Điều này có thể khắc phục?

Dưới đây là câu đố thể hiện vấn đề đầy đủ .

.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
Đây là một câu hỏi thú vị. Câu trả lời có thể có ở đây: iamvdo.me/en/blog/ từ
dwjohnston

2
trong trường hợp này bạn cần xác định trung tâm là gì . Đối với tôi, y thực sự là trung tâm và A có thể không. đừng nói chuyện khi chúng ta có họ phông chữ khác nhau, sự liên kết sẽ còn tồi tệ hơn
Temani Afif

1
Đó chỉ là cách các chữ cái hoạt động. Chúng được căn chỉnh, bởi vì phần vtrong yophần gnằm trên cùng một dòng với điểm thấp nhất cho chữ in hoa. Với logic của bạn,,, Ö sẽ được căn chỉnh giống như A và O nhưng chúng không thể. Nếu bạn muốn làm một cái gì đó đặc biệt về nó, bạn cần sử dụng javascript để kiểm tra xem đó có phải là một cái mũ nhỏ và sau đó đẩy nhân vật lên một vài ký tự.
Rickard Elimää

1
Tôi tò mò nếu có một câu trả lời hữu ích ở đây. Vấn đề dường như là những cái này thực sự là trung tâm. I E. nói rằng bạn có thể di chuyển y và g lên, nếu bạn có chữ thường thì sao? màn hình đó nên như thế nào?
dwjohnston

2
Mở phông chữ của bạn trong bất kỳ trình soạn thảo phông chữ. Chỉnh sửa mọi nhân vật cho đến khi bạn hài lòng với những gì bạn xem là "trung tâm" . Lưu và sử dụng như gia đình phông chữ hoàn toàn mới của bạn. Nên mất không quá 15 phút. Tôi không thấy cách nào lành mạnh khác ngoài SVG hoặc các mánh khóe khác bằng cách sử dụng canvas & co. Nhưng tôi sẽ nghĩ về câu hỏi này.
Roko C. Buljan

Câu trả lời:


4

Đây là giải pháp của tôi bằng cách sử dụng JS. Ý tưởng là biến phần tử thành hình ảnh để lấy dữ liệu của nó dưới dạng pixel sau đó lặp qua chúng để tìm đỉnh và đáy của mỗi ký tự và áp dụng bản dịch để sửa căn chỉnh. Điều này sẽ làm việc với các thuộc tính phông chữ động.

Mã không được tối ưu hóa nhưng nó làm nổi bật ý chính:

CẬP NHẬT

Đây là một tối ưu hóa đầu tiên của mã:

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>

Tôi đang sử dụng plugin dom-to-image cho việc này.


Một mite chạy chậm, nhưng đây là giải pháp hoạt động ổn định đầu tiên cho đến nay. (Với lời cảnh báo mà trung tâm kỹ thuật  trông có vẻ kỳ lạ.)
Brilliand

@Brilliand Tôi đã sử dụng một cách rõ ràng Âđể chứng minh rằng việc định tâm của anh ấy không tối ưu như tôi đã nhận xét trong câu trả lời của anh ấy;) Anh ấy có thể sẽ thay đổi suy nghĩ sau khi thấy điều này và chấp nhận cách hoạt động của phông chữ
Temani Afif

Điều này có vẻ khá tốt. Tôi nghĩ rằng tôi sẽ sử dụng nó, nếu tôi có thể làm cho nó hiệu quả hơn. Hiện tại có vẻ hơi chậm.
Chron Bag

@ChronBag vâng, bạn có thể làm việc với mã và tối ưu hóa nó, có chỗ cho việc này. Tôi đã không làm điều đó vì nó mất rất nhiều thời gian và nó không thực sự là mục đích của câu hỏi. Tôi muốn tập trung vào ý chính. Có lẽ sẽ làm sau này bằng cách này.
Temani Afif

@ChronBag đã thêm một tối ưu hóa, tôi đoán nhanh hơn một chút.
Temani Afif

1

Có thể có một câu trả lời tốt hơn, nhưng có vẻ như cách duy nhất là áp dụng thủ công các phong cách khác nhau tùy thuộc vào việc đó có phải là một trong:

  • Chữ viết hoa
  • Chữ thường có đuôi
  • Chữ thường có cuống
  • Chữ thường không

Bây giờ lưu ý rằng, theo hiểu biết của tôi, độ cao tương đối của đuôi và thân cây tôi nghĩ được xác định bởi phông chữ. Tôi không chắc có cách nào để truy cập chương trình đó không - vì vậy bạn có thể cần điều chỉnh các giá trị này bằng phông chữ.

Cũng lưu ý rằng giải pháp này sẽ không hoạt động để hỗ trợ nhiều ngôn ngữ - vì bạn sẽ cần xác định danh mục nào mà mỗi ký tự phù hợp với hàng tá bộ ký tự khác nhau.

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>


Tôi đã hy vọng tránh được điều gì đó như thế này, nhưng nó có thể là giải pháp duy nhất. Nếu không có gì khác đi cùng, có lẽ tôi sẽ sử dụng cái này. Cảm ơn
Chron Bag

2
Nếu chữ cái có thể là bất kỳ chữ cái unicode nào (từ bất kỳ bảng chữ cái nào), thì chữ này trở nên không khả thi.
Brilliand

Bạn quên ÂËâë
Temani Afif

À đúng rồi, điểm tốt @Brilliand Người dùng của tôi sẽ có thể sử dụng bất kỳ văn bản unicode nào cho tên hiển thị của họ, vì vậy giải pháp này thậm chí còn dễ vỡ hơn.
Chron Bag

0

Đây là một tình huống khó khăn!

Từ những gì tôi có thể nói, điều này sẽ khó thực hiện nhất có thể mở rộng (nghĩa là %, vwhoặc vhcác giá trị thay vì pxhoặc em). Nếu bạn cần làm cho nó trông đẹp hơn trên thiết bị di động hoặc máy tính bảng, vui lòng xem xét sử dụng giải pháp của tôi với các @mediađiểm dừng.

Giải pháp của tôi về cơ bản phát hiện nếu đó là một phần tử chữ thường có đuôi và thêm một lớp để bù chiều cao để bù cho phần đuôi.

Trong thử nghiệm của tôi, nó không xuất hiện mà bất cứ xử lý thêm được yêu cầu cho vốn chữ hoặc chữ thường chữ mà không cần một cái đuôi . Hãy thoải mái sửa tôi nếu tôi sai.

Có một JSFiddle nếu bạn muốn làm hỏng và thay đổi / kiểm tra giải pháp này.

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>

Hãy cho tôi biết suy nghĩ của bạn và nếu tôi bỏ lỡ bất cứ điều gì. Thật tuyệt khi có được giải pháp cuối cùng cho việc này vì bản thân tôi cũng từng gặp vấn đề tương tự!


Điều này dường như tương tự như giải pháp của dwjohnston và chịu những cạm bẫy tương tự như của ông. Tuy nhiên, nó được đánh giá cao, và tôi có thể sẽ đi cùng với một cái gì đó dọc theo những dòng này nếu không có gì lý tưởng hơn xuất hiện.
Chron Bag

Tôi giả sử như là phương sách cuối cùng, bạn có thể đi theo con đường đếm pixel - như được thấy ở đây, theo đó bạn sẽ phát hiện ra chiều cao thực tế của nó bằng pixel và sau đó áp dụng độ lệch thích hợp.
EGC

1
Vâng, tôi đã đề cập ý tưởng đó trong các ý kiến ​​cho OP. Có lẽ đó là con đường để đi.
Chron Bag

Xin lỗi về việc lưu ý ý tưởng của bạn một lần nữa .. quá nhiều ý kiến, rõ ràng đã bỏ lỡ nó!
EGC

-1

Bạn có thể sẽ cần một lớp trợ giúp cho việc này, để bạn có thể dịch các chữ cái viết thường nhiều hơn chữ in hoa. Một tập lệnh đơn giản có thể dễ dàng đặt các lớp trợ giúp này tự động.

Hy vọng điều này sẽ giải quyết vấn đề cho bạn :)

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


của bạn ykhông phải là trung tâm. Thêm một số nữa!
Roko C. Buljan

Tôi cũng không biết trước những chữ cái sẽ là gì.
Chron Bag

Tôi hiểu điều đó, nhưng một tập lệnh kiểm tra xem chữ cái là chữ hoa hay chữ thường và đặt một lớp trợ giúp trên HTML dựa trên điều đó sẽ khắc phục điều đó một cách dễ dàng :)
Ragna Roaldset 18/11/19

@RagnaRoaldset Tôi nghĩ rằng anh ấy không có nghĩa là chữ hoa hoặc chữ thường. Ông có nghĩa là có chữ thường nhưng hình dạng khác nhau của nhân vật. So sánh oybạn sẽ có được điều đó. Các nhân vật có đuôi tạo ra vấn đề ở vị trí đầu tiên (được đề cập trong bài).
Anna

1
Bạn luôn có thể tạo một mảng cho tất cả các chữ cái có đuôi và lặp qua nó để kiểm tra xem chữ cái trong div có khớp không trước khi áp dụng lớp :) Nhưng tôi hiểu rồi, chỉ cần cố gắng đưa ra giải pháp :) hy vọng ai đó sẽ đưa ra giải pháp nó :)
Ragna Roaldset
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.