web-dev-qa-db-ja.com

擬似要素の中央揃え

初めて擬似:afterセレクターを実際に使用します。私が遭遇している問題がそれの制限なのか、それとも明らかな何かを見逃しているのかはわかりません。

これが私のライブコードです.

li.current:after {
    border-width: 1px 1px 0 0;
    content: ' ';
    background: #256f9e;
    display: block;
    height: 13px;
    position: absolute;
    width: 10px;
    top: 6;
    margin:0px auto;
    z-index: 99;
    transform: rotate(-224deg);
    -webkit-transform: rotate(-224deg);
    -moz-transform: rotate(-224deg);
    -ms-transform: rotate(-224deg);
    -o-transform: rotate(-224deg);
    transform-Origin: 50% 50%;
    -webkit-transform-Origin: 50% 50%;
    -moz-transform-Origin: 50% 50%;
    -ms-transform-Origin: 50% 50%;
    -o-transform-Origin: 50% 50%;
    text-align: center;
    float: center;
}

小さな三角形(または、三角形のように回転したボックス)を作成しました。 <li></li>の中央に配置したいのですが、通常の方法では理解できません。失敗したもの(順不同):

text-align: center;
float: center;
margin: 0 auto;
margin-right: 0;
margin-left: 0;

私は何が欠けていますか?私はそれが重要だとは思いませんが、AngularJSを使用しています。 Angular&Pseudo selectors(これは疑わしい)。

43
EnigmaRM

問題は、absoluteポジショニングの使用と、それを試して中央に配置するために使用している方法です。要素を絶対に配置すると、ol 'margin: 0 auto;メソッドは物事を中央に配置できません。これが質問の最後にある理由について説明しますが、これを機能させたい場合は、まず解決策に取り掛かりましょう。

ここにいくつかの作業コードがあります。 JSFiddleで表示

#tool-menu li {
  ...
  position: relative;
}

li.current:after {
  ...
  position: absolute;
  width: 10px;
  top: 6;
  left: 50%;
  margin-left: -5px;
}

ここで何が起こっているのかを分析しましょう。

新しい包含ブロックのセットアップ

元のFiddleでは、擬似要素はビューポートに対して絶対的に配置されます。例は、これが何を意味するのか、なぜこれが望ましくないのかを示す最良の方法かもしれません。 top: 0に設定することを検討してください。これにより、親(li)ではなく、ブラウザウィンドウ(またはこの場合はJSFiddleフレーム)の上部にラッチされたままになります。そのため、メニューがページの下部にある場合、または移動している場合でも、擬似要素はページの上部に固定され、それとは無関係にフローティング状態になります。

これは、親要素の位置を明示的に設定しない場合の絶対配置要素のデフォルトの動作です。私たちが望むのは、親に対して相対的な位置を定義することです。これを行うと、それがどこにあっても、擬似要素は親に固執します。

これを実現するには、親#tool-menu liを明示的に配置する必要があります(つまり、position: static以外に設定する必要があります)。 position: relative;の使用を選択した場合、ページ上の親の計算された位置は変更されず、必要な処理が行われます。だからそれを使ったのです。

技術的には、ここで行っているのは、子用に新しい ブロックを含む を作成することです。

擬似要素の配置

絶対位置は親を基準にして決定されるので、パーセンテージを使用して子を配置する場所を定義できるという事実を利用できます。この場合、中央に配置したいので、left: 50%に設定します。

ただし、これだけを行うと、疑似要素の左端が50%に並ぶことがわかります。これは私たちが望むものではありません-擬似要素の中心を中央にしたいのです。そして、それがマイナスmargin-leftを追加した理由です。これにより、それを少しスクートして、中央を親の中心に合わせます。

そして、それを行うと、それは中央になります!素晴らしい!

margin: auto;が機能しなかったのはなぜですか?

マージンの自動値は、かなり複雑なアルゴリズムから計算されます。時々、計算は0になります。経験から、これがそのような出来事の1つの例であることを知っていますが、正確な理由を確認するためのアルゴリズムをまだ追跡していません。それを実行したい場合は、 ほとんどのブラウザが実装している可能性が最も高い仕様を見てください。

90
jamesplease

calcを使用して中央揃えする

Cssでcalc関数を使用して、擬似要素を中央に配置することもできます。

注:これはIE8以前ではサポートされていません( caniuse )が、古いブラウザーにフォールバックを提供できます。

これで表示 コードペン 。また、MarkPのcss borderメソッドを使用して三角形を描画しています。

li.current:after {
  content: '';
  display: block;
  height: 0;
  position: absolute;
  width: 0;
  overflow: hidden;
  bottom: -5px;
  left: calc(50% - 5px);
  z-index: 2;
  border-top: 5px #256f9e solid;
  border-left: 5px transparent solid;
  border-right: 5px transparent solid;
}
9
Mark Reilly

幅をパーセンテージで定義し、ブロック要素にして中央にテキストを配置する方が良いでしょうか?

「フロート:中央;」は無効であり、動作しません。フローティング要素と絶対配置要素を混在させると、レイアウトがうまく機能しないため、レイアウトで問題が発生する確実な方法です。

次のようなものを試してください:

li.current:after {
content: 'YOUR CONTENT';
display: block;
width: 100%;
text-align: center; }
3
Hexdom

直接関連していません(すでにjmeasに投票しています)が、CSSボーダートリックを使用して三角形を作成する方が簡単な場合もあります。例えば.

li.current:after {
    content: '';
    display: block;
    height: 0;
    position: absolute;
    width: 0;
    overflow:hidden;
    bottom: 0;
    left: 50%;
    margin: 0 0 -5px -5px;
    z-index: 99;
    border-top: 5px #256f9e solid;
    border-left: 5px transparent solid;
    border-right: 5px transparent solid;
}

垂直配置に関してjmeasが提案したものと同様の戦術。下に揃えてから、負のマージン底を使用して、これを目的の位置に押し出します。

3
MarkP

margin:autoを使用して中央に配置

要素の幅が宣言されている限り、絶対的なセンタリング方法を使用できます。

このメソッドを使用するには、0を有効にするために、rightおよびleftプロパティをmargin: autoに設定する必要があります。

このメソッドを拡張して、水平方向のセンタリングも実装できます。

詳細については、リンクを参照してください。

http://www.smashingmagazine.com/2013/08/09/absolute-horizo​​ntal-vertical-centering-css/

li.current:after {
  content: "";
  position: absolute;
  display: block;
  right: 0;
  bottom: -5px;
  left: 0;
  margin: auto;
  border-width: 5px;
  border-style: solid;
  border-color: transparent;
  border-top-color: #256f9e;
  width: 200px;
  height: 200px;
}

ul {
  list-style-type: none;
  padding: 0;
  margin: 0;
}
<div>
  <ul>
    <li class="current"></li>
  </ul>
</div>
1
user1095118