31859


リストのaタグを親要素いっぱいにして、さらにテキストを上下中央にしたいのですが、うまくいきません。  
レスポンシブサイトなので下記のように特殊なやり方で上下左右中央にテキストをもってきています。

[code]

    .u-centaring-all-item-height-flexible {
      position: absolute;
      top: 50%;
      left: 0;
      right: 0;
      -webkit-transform: translateY(-50%);
      transform: translateY(-50%);
    }
    
[/code]

<https://codepen.io/anon/pen/QdEYyZ>

[code]

    .u-d-b {
      height: 100%;
      display: table-cell;
      vertical-align: middle;
    }
    
    .u-color-black {
      color: #000;
    }
    
    .u-centaring-all-item-height-flexible {}
    
    a {
      margin: 0;
      padding: 0;
      font-size: 100%;
      background: transparent;
      text-decoration: none;
      color: #FFF;
    }
    
    
    /* 下記li　上記a */
    
    .u-centaring-all-parent-height-flexible {
      position: relative;
      display: table;
    }
    
    .c-gnavi__list--green {
      background-image: linear-gradient(to top, #7a32, #da59 40%, #9ffc9d);
    }
    
    .c-gnavi__list {
      width: 32%;
      height: 60px;
      margin-right: .5%;
      padding: .1rem 1rem;
      box-shadow: 1px 1px 1px rgba(0, 0, 0, .75);
      text-align: center;
      font-size: 1.4rem;
    }
    
    html,
    body,
    div,
    span,
    object,
    iframe,
    h1,
    h2,
    h3,
    h4,
    h5,
    h6,
    blockquote,
    pre,
    abbr,
    address,
    cite,
    code,
    del,
    dfn,
    em,
    img,
    ins,
    kbd,
    q,
    samp,
    small,
    strong,
    sub,
    sup,
    var,
    b,
    i,
    dl,
    dt,
    dd,
    ol,
    ul,
    li,
    fieldset,
    form,
    label,
    legend,
    table,
    caption,
    tbody,
    tfoot,
    thead,
    tr,
    th,
    td,
    article,
    aside,
    canvas,
    details,
    figcaption,
    figure,
    footer,
    header,
    hgroup,
    menu,
    nav,
    section,
    summary,
    time,
    mark,
    audio,
    video {
      margin: 0;
      padding: 0;
      border: 0;
      outline: 0;
      vertical-align: baseline;
      background: transparent;
    }
    
    * {
      -ms-box-sizing: border-box;
      -o-box-sizing: border-box;
      box-sizing: border-box;
    }
    
    *,
     :before,
     :after {
      background-repeat: no-repeat;
      box-sizing: inherit;
    }
    
    user agent stylesheet li {
      display: list-item;
      text-align: -webkit-match-parent;
    }
    
    Inherited from ul.c-gnavi .c-gnavi {
      width: 100%;
      color: black;
      color: #000!important;
    }
    
    nav ol,
    nav ul {
      list-style: none;
    }
    
    ul {
      list-style: none;
    }
    
    user agent stylesheet ul,
    menu,
    dir {
      display: block;
      list-style-type: disc;
      -webkit-margin-before: 1em;
      -webkit-margin-after: 1em;
      -webkit-margin-start: 0px;
      -webkit-margin-end: 0px;
      -webkit-padding-start: 40px;
    }
    
    Inherited from nav.c-gnavi.u-mb-9percent .c-gnavi {
      width: 100%;
      color: black;
      color: #000!important;
    }
    
    Inherited from body body {
      margin: auto;
      background-image: url(../img/common-img/back-img.png);
      font-family: -apple-system, Helvetica Neue, Hiragino Kaku Gothic ProN, '游ゴシック', 'メイリオ', meiryo, sans-serif;
      font-size: 1.6rem;
      line-height: 1.6;
      letter-spacing: .1rem;
      color: #000;
    }
    
    Inherited from html html {
      font-size: 62.5%;
    }
    
    html {
      box-sizing: border-box;
      cursor: default;
      font-family: sans-serif;
      line-height: 1.5;
      -ms-text-size-adjust: 100%;
      -webkit-text-size-adjust: 100%;
    }
    
    Pseudo ::before element:before,
     :after {
      text-decoration: inherit;
      vertical-align: inherit;
    }
    
    *,
     :before,
     :after {
      background-repeat: no-repeat;
      box-sizing: inherit;
    }
    
    Pseudo ::after element:before,
     :after {
      text-decoration: inherit;
      vertical-align: inherit;
    }
    
    *,
     :before,
     :after {
      background-repeat: no-repeat;
      box-sizing: inherit;
    }
    
    Pseudo ::selection element::selection {
      background-color: #b3d4fc;
      color: #000;
      text-shadow: none;
    }
[/code]

[code]

    <li class="c-gnavi__list c-gnavi__list--green u-centaring-all-parent-height-flexible u-is-hover-opacy-weak"><a class="u-color-black u-centaring-all-item-height-flexible u-d-b" href="http://l.jp/index.html">LLLLLLL</a></li>
[/code]

このような特殊なことをしなければdisplay:block;で親要素いっぱいになりますが、  
上記のような場合はどのようにすれば実現できますか？

height:100%;にすると親いっぱいにはできますが、今度はテキストが上にずれてしまいます。

その後下記のようにしたところだいたい真ん中に来たのですが原理がよくわかりません。  
なぜheightを100%にするとtop: 80%;に変更しないといけないのでしょうか？

[code]

    .u-centaring-all-item-height-flexible {
        position: absolute;
        top: 80%;
        left: 0;
        right: 0;
        -webkit-transform: translateY(-50%);
        transform: translateY(-50%);
    }
    
[/code]

transform: translateY(-50%)  
が要素の高さの半分だけ上に移動するということですよね。

aの高さを100%にすると上記のままだと親要素の高さ割る2分aが上に移動するので、  
aの高さが大きくなった分上にずれすぎるのが原因ということですね。

何となく理論はわかったのですが、  
transform: translateY(-25%);にしてもまだ上にずれ  
transform: translateY(-20%); */にしたらだいたい真ん中に来ました。

aの中のテキストがaの上ぞろえになってしまっているのですが、vertical-align: middle;をつけてもなぜ上下中央にならないのでしょうか？  
height: 100%;  
vertical-align: middle;  
transform: translateY(-20%);

・  
＞＞＞  
また、ブロックボックス内のテキストなどの縦方向の配置を制御することはできません。

これはとっても大事な情報ですね。  
テキストならブロック要素内でも効くと思っていました。  
インライン要素内のテキストしか上下中央にできないのですね。  
例  
spanの中のテキスト 〇  
divの中のてきすと ×

・インライン要素に適用した場合には、行ボックスの高さの範囲内での縦方向の位置を指定します。  
これはおそらく親要素をはみ出るような指定はできないということですかね？

結論  
vertical-align プロパティを適用できるのは、インライン要素とテーブルセルのみ。  
ブロック要素自体やその中にあるテキストやインライン要素には効かない。

・下記をulにつけてaにheight:100%;を付けたのですが、それでもうまくいきません。

[code]

    .u-flexiblebox-centaring-all {
        display: flex;
        align-items: center; /* 縦方向中央揃え */
        justify-content: center; /* 横方向中央揃え */
    }
    
[/code]

やはりdislpey:table;出ないとだめなのでしょうか？


CC BY-SA 4.0
2017-01-14T12:48:17.473
31846
2019-12-13T19:51:46.750
2019-12-13T19:51:46.750
32986
14320
question
css
リストのaタグを親要素いっぱいにして、さらにテキストを上下中央にしたい


**_下記のように特殊なやり方で上下左右中央にテキストをもってきています_**

本当に特殊なやり方ですね。どこから引っ張ってこられたコードか知りませんが、何が起こっているのかをちゃんと理解せずに使うとご質問に記載のような状況が発生してしまいます。

[code]

     ↓親BOX(li)
     +------------------------------------------+  -
     |                                          |  |
     |                                          |  |
     |                                          |  |
     |+----------------------------------------+|  |  ↑ transform: translateY(-50%) (子BOX相対)
     ++            子(a)側のコンテンツ            ++  ↓ TOP: 50% (親BOX相対)
     |+----------------------------------------+|
     |                                          |
     |                                          |
     |                                          |
     +------------------------------------------+
    
[/code]

この状況で子側のheightが100%になったらどうなるか、想像できると思うのですが…。

[code]

     ↓親BOX(li)
     ++----------------------------------------++  -  ↑ transform: translateY(-50%) (子BOX相対)
     ||            子(a)側のコンテンツ            ||  |  |
     ||                                        ||  |  |
     ||                                        ||  |  |
     ||                                        ||  |  |
     ++                                        ++  ↓ TOP: 50% (親BOX相対)
     ||                                        ||
     ||                                        ||
     ||                                        ||
     ||                                        ||
     ++----------------------------------------++
    
[/code]

つまりあなたが使っておられる`u-centaring-all-item-height-
flexible`のスタイル指定は、子側の高さがちょうどコンテンツの高さになっていることが大前提なので、子側のheightを100%に指定して、親側と同じ高さになってしまっては、コンテンツを上下中央に配置することはできません。

`top: 80%;`でほぼ中央とのことですが、この調整方法では結局、親側のheightと現在のfont-
size等に依存することになり、ピクセル単位で微調整をかけているのと同じことで、とてもレスポンシブとは言えないことになってしまいます。

* * *

どうしても`u-centaring-all-item-height-
flexible`を使いたいのであれば、a要素を親にしてその子要素を中央に表示すると言った形にする必要があるでしょう。

[code]

    a.full-height {
      height: 100%;
    }
    p.sub-content {
      margin: 0;
    }
    li.block-list {
      display: block;
    }
    
    .u-d-b {
        display: block!important;
    }
    .u-color-black {
        color: #000;
    }
    .u-centaring-all-item-height-flexible {
        position: absolute;
        top: 50%;
        left: 0;
        right: 0;
        -webkit-transform: translateY(-50%);
        transform: translateY(-50%);
    }
    a {
        margin: 0;
        padding: 0;
        font-size: 100%;
        vertical-align: baseline;
        background: transparent;
        text-decoration: none;
        color: #FFF;
    }
    .u-centaring-all-parent-height-flexible {
        position: relative;
    }
    .c-gnavi__list {
        width: 32%;
        height: 60px;
        margin-right: .5%;
        padding: .1rem 1rem;
        box-shadow: 1px 1px 1px rgba(0,0,0,.75);
        text-align: center;
        font-size: 1.4rem;
    }
    html, body {
      width: 100%;
      height: 100%;
    }
    body {
      margin: 0;
    }
[/code]

[code]

    <div>
      <li class="c-gnavi__list block-list">
        <a class="u-color-black u-d-b u-centaring-all-parent-height-flexible full-height" href="http://ja.stackoverflow.com/">
          <p class="u-centaring-all-item-height-flexible sub-content">LLLLLLL</p>
        </a>
      </li>
    </div>
[/code]

* * *

**最初の回答後の追記部分について**

**_`transform: translateY(-25%);`にしてもまだ上にずれ  
`transform: translateY(-20%);` にしたらだいたい真ん中に来ました。_**

ざっくりとこんな状態だということですね。

[code]

     ↓親B(li)
     +------------------------------------------+  -
     |                                          |  |
     |                                          |  |
     |+----------------------------------------+|  |  ↑ transform: translateY(-25%) (子BOX相対)
     ||            子(a)側のコンテンツ            ||  |  |
     ||                                        ||  |  |
     +|                                        |+  ↓ TOP: 50% (親BOX相対)
     ||                                        ||
     ||                                        ||
     |+                                        +|
     ||                                        ||
     ||                                        ||
     +|                                        |+
      |                                        |
      |                                        |
      +----------------------------------------+
    
[/code]

補正しないといけない量は親BOXの高さ(=子BOXの高さ)ではなく、「子BOXのコンテンツの高さ」から求めないといけません。 ** _`transform:
translateY(-20%);`にしたらだいたい真ん中_** と言うのも **現在の**
「親BOXの高さ」「子BOXのコンテンツの高さ」の場合、たまたまその値で大体真ん中にきている、と言うだけで、両者の比率が大きく異なってくるとその値ではダメなはずです。試しにaタグ内のフォントサイズを倍くらいに増やしてみてください。

**_aの中のテキストがaの上ぞろえになってしまっているのですが、`vertical-align:  
middle;` をつけてもなぜ上下中央にならないのでしょうか？_**

`vertical-
align`の仕様に関しては、Webデザインに関わるものは戸惑うところが多いのですが、その分、日本語でしっかり解説してくれているサイトも多いのでよく探してみてください。

[vertical-align－スタイルシートリファレンス -
HTMLクイックリファレンス](http://www.htmq.com/style/vertical-align.shtml)

上の記事で言うと、肝心なのはこの辺りでしょうか。

>   * `vertical-align` プロパティは、ブロックレベル要素には適用できません。従って、 `vertical-align`
> プロパティでブロックボックス全体の縦方向の配置を制御することはできません。また、ブロックボックス内のテキストなどの縦方向の配置を制御することはできません。
>   * インライン要素に適用した場合には、行ボックスの高さの範囲内での縦方向の位置を指定します。
>

あなたのCSSだとaタグを`display:block`で使っておられますから、a要素には`vertical-align:
middle;`は全く効かず、その下位要素のインラインテキストに対して _行ボックスの高さの範囲内_
で縦方向の位置が指定されているだけ、と言う形になります。

と言うわけで、その記事の中にあるこちら:

>   * `vertical-align` プロパティを適用できるのは、インライン要素とテーブルセルです。
>

が最後の部分↓につながるわけです。

* * *

**さらに追記**

**_これはおそらく親要素をはみ出るような指定はできないということですかね？_**

と言うよりは、インライン要素同志の縦位置合わせだけができると思った方がいいですね。色々なフォントサイズのインライン要素を横に並べて、vertical-
alignの指定を変えていくと雰囲気がわかると思います。

  * **_下記をulにつけてaにheight:100%;を付けたのですが、それでもうまくいきません。_**

`align-items: center;`の効果も、その内部のコンテンツを縦方向で中央に揃えるものではありません。

flexbox絡みのわかりやすい解説記事も増えてきましたから、図でわかりやすく示してくれているサイトを見つけてください。

[【CSS】Flexboxのプロパティ（justify-content、align-items、align-self、align-
content）を紹介します](http://scene-live.com/page.php?page=59)

あなたが期待されているのとは異なる図だと思います。`center`については、様々なfont-sizeのインライン要素を`vertical-align:
middle;`で並べたときのイメージに近いですね。

**_やはりdislpey:table;出ないとだめなのでしょうか？_**

私の知識の範囲では「絶対ダメ」かどうかはわかりませんが、簡単かつ確実とは言えると思います。  
(もっとも`table-
cell`なんかを指定した要素は特殊なレイアウトになるので、通常のCSSで期待したのと結果が異なるなんてことが別に出てくるかもしれません。)

* * *

**さらにさらに追記**

縦中央をレスポンシブに実現するのは結構大変なので、`display: table-
cell;`なんかを使った方が確実でわかりやすいと思うのですが…を実際にコードにしてみました。

[code]

    a.vertical-middle-cell {
      display: table-cell;
      vertical-align: middle;
    }
    p.sub-content {
      margin: 0;
    }
    li.cell-container {
      display: table;
    }
    
    .u-color-black {
        color: #000;
    }
    a {
        margin: 0;
        padding: 0;
        font-size: 100%;
        background: transparent;
        text-decoration: none;
        color: #FFF;
    }
    .c-gnavi__list {
        width: 32%;
        height: 60px;
        margin-right: .5%;
        padding: .1rem 1rem;
        box-shadow: 1px 1px 1px rgba(0,0,0,.75);
        text-align: center;
        font-size: 1.4rem;
    }
    html, body {
      width: 100%;
      height: 100%;
    }
    body {
      margin: 0;
    }
[/code]

[code]

    <div>
      <li class="c-gnavi__list cell-container">
        <a class="u-color-black vertical-middle-cell" href="http://ja.stackoverflow.com/">LLLLLLL</a>
      </li>
    </div>
[/code]

  * `a`タグの親要素の`li`にも`display: table;`なんてのを指定しています
  * `a`タグに`vertical-align: middle;`の指定をお忘れなく

と言ったところでしょうか。お試しください。


CC BY-SA 3.0
2017-01-15T03:55:40.033
31859
2017-01-15T12:05:52.127
2017-01-15T12:05:52.127
13972
13972
31846
answer