CSSのすべてのテキストを垂直方向に配置するにはどうすればよいですか?


12

問題は次のように、特定の文字のようですgyq斜面の下には、垂直方向のセンタリングを可能にするものではないことを、尾を持っている、など。ここに問題を紹介する画像があります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は実際には中央に配置され、Aはそうではないかもしれません。異なるフォントファミリがある場合は話さないでください。配置はさらに悪化します
Temani Afif

1
それが文字のしくみです。ので、彼らは、整列しているvyoで一部がg大文字のための最低点と同じ行にあります。あなたの論理では、Å、Ä、ÖはAとOと同じように整列しますが、整列することはできません。それについて何か特別なことをしたい場合は、JavaScriptを使用して、それがスモールキャップかどうかを確認し、文字を数文字上に移動する必要があります。
リッカードエリマ

1
ここに役立つ答えがあるかどうか知りたいです。問題は、これらが本当に中心に置かれていることです。すなわち。yとgを上に移動できるとしたら、小文字のaがあるとどうでしょうか。それはどのように表示すべきですか?
dwjohnston

2
任意のフォントエディタでフォントを開きます。「中央に配置された」と表示される内容に満足するまで、すべてのキャラクターを編集します。保存して、新しいフォントファミリとして使用します。15分以内にしてください。canvas&coを使用するSVGやその他の策略以外に、他の健全な方法はありません。しかし、私はこの質問について考えます。
ロコC.ブルジャン

回答:


4

これがJSを使った私の解決策です。アイデアは、要素を画像に変換してデータをピクセルとして取得し、それらをループして各文字の上部と下部を見つけ、平行移動を適用して配置を修正することです。これは、動的フォントプロパティで機能します。

コードは最適化されていませんが、主なアイデアを強調しています。

更新

これがコードの最初の最適化です。

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私Âは彼の回答でコメントしたように、彼のセンタリングが最適ではないことを明示的に示していました;)彼はおそらくこれを見て、フォントが機能する方法を受け入れた後、彼の心を変えるでしょう
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文字である場合、これは機能しなくなります。
ブリリアント

ÂËandを忘れるâë
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は中心にありません。もう少しT週間!
ロコC.ブルジャン

また、手紙がどうなるかは、前もってわかりません。
Chron Bag

私はそれを理解していますが、文字が大文字か小文字かをチェックし、それに基づいてHTMLにヘルパークラスを配置するスクリプトは、それを簡単に修正します:)
Ragna Roaldset

@RagnaRoaldset彼は大文字も小文字も意味しないと思います。彼は小文字だが異なる形の文字があることを意味した。比較するoy、それがわかります。尾を持つキャラクターは、最初に問題を作成します(ポストで言及)。
アンナ

1
あなたは常に尾を持つすべての文字の配列を作成し、クラスを適用する前にdiv内の文字が一致するかどうかを確認するためにループすることができます:)しかし、私はそれを取得しました: it :)
Ragna Roaldset
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.