いくつかの列があり、そのうちのいくつかを次の値に変更したいとします。
<div class="container">
<div class="statusColumn"><span>Normal</span></div>
<div class="statusColumn"><a>Normal</a></div>
<div class="statusColumn"><b>Rotated</b></div>
<div class="statusColumn"><abbr>Normal</abbr></div>
</div>
このCSSの場合:
.statusColumn b {
writing-mode: tb-rl;
white-space: nowrap;
display: inline-block;
overflow: visible;
transform: rotate(-90deg);
transform-Origin: 50% 50%;
}
最終的には次のようになります。
テキストが他の要素と重ならないように、回転した要素がその親の高さに影響するようなCSSを書くことは可能ですか?このようなもの:
90度回転させたいと仮定すると、これはテキスト以外の要素でも可能です-しかし、CSSの多くの興味深いものと同様に、少し巧妙なことが必要です。私のソリューションはまた、CSS 2仕様に従って未定義の動作を技術的に呼び出します。したがって、Chrome、Firefox、Safari、およびEdgeで動作することをテストおよび確認しましたが、将来的に壊れないことはお約束できませんブラウザのリリース。
.element-to-rotate
...を回転させるこのようなHTMLを指定します.
<div id="container">
<something class="element-to-rotate">bla bla bla</something>
</div>
...回転させたい要素の周りにtwoラッパー要素を導入します:
<div id="container">
<div class="rotation-wrapper-outer">
<div class="rotation-wrapper-inner">
<something class="element-to-rotate">bla bla bla</something>
</div>
</div>
</div>
...そして、次のCSSを使用して反時計回りに回転します(または、コメントアウトされたtransform
を時計回りの回転に変更する方法を参照してください)。
.rotation-wrapper-outer {
display: table;
}
.rotation-wrapper-inner {
padding: 50% 0;
height: 0;
}
.element-to-rotate {
display: block;
transform-Origin: top left;
/* Note: for a CLOCKWISE rotation, use the commented-out
transform instead of this one. */
transform: rotate(-90deg) translate(-100%);
/* transform: rotate(90deg) translate(0, -100%); */
margin-top: -50%;
/* Not vital, but possibly a good idea if the element you're rotating contains
text and you want a single long vertical line of text and the pre-rotation
width of your element is small enough that the text wraps: */
white-space: nowrap;
}
p {
/* Tweak the visuals of the paragraphs for easier visualiation: */
background: pink;
margin: 1px 0;
border: 1px solid black;
}
.rotation-wrapper-outer {
display: table;
}
.rotation-wrapper-inner {
padding: 50% 0;
height: 0;
}
.element-to-rotate {
display: block;
transform-Origin: top left;
/* Note: for a CLOCKWISE rotation, use the commented-out
transform instead of this one. */
transform: rotate(-90deg) translate(-100%);
/* transform: rotate(90deg) translate(0, -100%); */
margin-top: -50%;
/* Not vital, but possibly a good idea if the element you're rotating contains
text and you want a single long vertical line of text and the pre-rotation
width of your element is small enough that the text wraps: */
white-space: nowrap;
}
<div id="container">
<p>Some text</p>
<p>More text</p>
<div class="rotation-wrapper-outer">
<div class="rotation-wrapper-inner">
<p class="element-to-rotate">Some rotated text</p>
</div>
</div>
<p>Even more text</p>
<img src="https://i.stack.imgur.com/ih8Fj.png">
<div class="rotation-wrapper-outer">
<div class="rotation-wrapper-inner">
<img class="element-to-rotate" src="https://i.stack.imgur.com/ih8Fj.png">
</div>
</div>
<img src="https://i.stack.imgur.com/ih8Fj.png">
</div>
上記で使用した呪文に対する混乱は合理的です。多くのことが行われていますが、全体的な戦略は簡単ではなく、CSSトリビアの知識が必要です。順を追って説明しましょう。
私たちが直面する問題の核心は、 transform
CSSプロパティを使用して要素に適用される変換はすべて、レイアウトが行われた後に発生することです。つまり、要素でtransform
を使用しても、その親または他の要素のサイズや位置にはまったく影響しません。 transform
の動作方法に関するこの事実を変更する方法はまったくありません。したがって、要素を回転させ、その親の高さを回転に合わせる効果を作成するには、次のことを行う必要があります。
.element-to-rotate
の幅と等しいother要素を構築します.element-to-rotate
に記述します。ステップ1の要素は.rotation-wrapper-outer
でなければなりません。しかし、どのようにしてそのheightを.element-to-rotate
のwidthと等しくすることができますか?
ここでの戦略の重要なコンポーネントは、padding: 50% 0
上の.rotation-wrapper-inner
です。このエクスプロイトの padding
の仕様のエキセントリックな詳細 :padding-top
およびpadding-bottom
であっても、その割合のパディングは常にの割合として定義されます要素のコンテナの幅。これにより、次の2段階のトリックを実行できます。
display: table
に.rotation-wrapper-outer
を設定します。これにより、 shrink-to-fit width になります。これは、コンテンツの固有の幅に基づいて、つまり.element-to-rotate
の固有の幅に基づいて幅が設定されることを意味します。 。 (サポートしているブラウザーでは、width: max-content
でこれをよりきれいに達成できますが、2017年12月の時点で、max-content
は Edgeではまだサポートされていません です。).rotation-wrapper-inner
のheight
を0に設定し、そのパディングを50% 0
に設定します(つまり、上部50%、下部50%)。これにより、親の幅の100%に等しい垂直方向のスペースが使用されます。これは、ステップ1のトリックにより、.element-to-rotate
の幅に等しくなります。次に、子要素の実際の回転と配置を実行するだけです。当然、transform: rotate(-90deg)
は回転を行います。 transform-Origin: top left;
を使用して、回転した要素の左上隅の周りで回転を発生させます。これにより、回転した要素が描画された場所のすぐ上に残るため、後続の翻訳の推論が容易になります。次に、translate(-100%)
を使用して、要素を回転前の幅に等しい距離だけ下にドラッグします。
.rotation-wrapper-outer
の50%の上部パディングのためにまだオフセットする必要があるため、それでもまだ正しい位置を取得できません。 .element-to-rotate
にdisplay: block
があることを確認して(マージンが適切に機能するように)、-50%margin-top
を適用します-マージンの割合はalso親要素の幅に対して定義されます。
以上です!
仕様のパディングとマージンの割合の定義からの次の注意 (ボルディング鉱山):
パーセンテージは、生成されたボックスの 包含ブロック のwidthに関して計算されます- 'padding-top' および 'padding-bottom' 。 包含ブロックの幅がこの要素に依存する場合、結果のレイアウトはCSS 2.1で定義されません。
全体のトリックは、内側のラッパー要素のパディングをその子の幅に依存するコンテナの幅に相対的にすることを中心に展開されているため、この条件に達し、未定義の動作を呼び出しています。現時点では、4つの主要なブラウザーすべてで動作します-.rotation-wrapper-inner
を親ではなく.element-to-rotate
の兄弟に変更するなど、仕様に準拠しているように見える一部の調整方法とは異なります。
残念ながら(?)これは、要素を回転させたとしても、一定の幅と高さを持ちながらも、回転後も変わらないということです。視覚的に変更しますが、物を回転させるとサイズが変更される非表示のラッピングボックスはありません。
90°未満で回転することを想像してください(例:transform: rotate(45deg)
):回転しているオブジェクトの元の寸法と実際の回転値に基づいてあいまいな寸法を持つ、このような不可視のボックスを導入する必要があります。
突然、回転したオブジェクトのwidth
とheight
だけでなく、その周りの「見えないボックス」のwidth
とheight
もあります。 。このオブジェクトの外側の幅を要求することを想像してください-それは何を返しますか?オブジェクトの幅、または新しいボックス?両方をどのように区別しますか?
したがって、この動作を修正するために記述できる(または「自動化」する必要がある)CSSはありません。もちろん、親コンテナのサイズを手動で増やすことも、JavaScriptを記述してそれを処理することもできます。
(明確にするために、 element.getBoundingClientRect
を使用して、前述の四角形を取得してみてください)。
仕様に記載 :
HTML名前空間では、transformプロパティは、変換された要素を囲むコンテンツのフローに影響しません。
これは、手動で変更しない限り、変換しているオブジェクトの周囲のコンテンツに変更が加えられないことを意味します。
オブジェクトを変換するときに考慮される唯一のものは、オーバーフロー領域です。
(...)オーバーフロー領域の範囲は、変換された要素を考慮します。この動作はに似ていますが、要素が相対位置調整によってオフセットされるとどうなりますか 。
position: relative
-オブジェクトを動かしても、周囲のコンテンツは変化しません( example )。
JavaScriptを使用してこれを処理する場合は、 this の質問をご覧ください。
padding
にパーセンテージを使用し、コンテンツをプッシュするために擬似要素を使用します。 JSFiddleでは、擬似要素を赤のままにして表示し、テキストのシフトを補正する必要がありますが、それが道だと思います。
.statusColumn {
position: relative;
border: 1px solid #ccc;
padding: 2px;
margin: 2px;
width: 200px;
}
.statusColumn i, .statusColumn b, .statusColumn em, .statusColumn strong {
writing-mode: tb-rl;
white-space: nowrap;
display: inline-block;
overflow: visible;
-webkit-transform: rotate(-90deg);
-moz-transform: rotate(-90deg);
-ms-transform: rotate(-90deg);
-o-transform: rotate(-90deg);
transform: rotate(-90deg);
-webkit-transform: rotate(-90deg);
/* also accepts left, right, top, bottom coordinates; not required, but a good idea for styling */
-webkit-transform-Origin: 50% 50%;
-moz-transform-Origin: 50% 50%;
-ms-transform-Origin: 50% 50%;
-o-transform-Origin: 50% 50%;
transform-Origin: 50% 50%;
/* Should be unset in IE9+ I think. */
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);
}
.statusColumn b:before{ content:''; padding:50% 0; display:block; background:red; position:relative; top:20px
}
<div class="container">
<div class="statusColumn"><span>Normal</span></div>
<div class="statusColumn"><a>Normal</a></div>
<div class="statusColumn"><b>Rotated</b></div>
<div class="statusColumn"><abbr>Normal</abbr></div>
</div>
このソリューションの概要は、ここにあります: http://kizu.ru/en/fun/rotated-text/
G-Cyrのコメント が正しく指摘しているように、 writing-mode
の現在のサポートはまともです です。単純な回転と組み合わせると、正確な結果が得られます。以下の例を参照してください。
.statusColumn {
position: relative;
border: 1px solid #ccc;
padding: 2px;
margin: 2px;
width: 200px;
}
.statusColumn i,
.statusColumn b,
.statusColumn em,
.statusColumn strong {
writing-mode: vertical-rl;
transform: rotate(180deg);
white-space: nowrap;
display: inline-block;
overflow: visible;
}
<div class="container">
<div class="statusColumn"><span>Normal</span></div>
<div class="statusColumn"><a>Normal</a></div>
<div class="statusColumn"><b>Rotated</b></div>
<div class="statusColumn"><abbr>Normal</abbr></div>
</div>
my other answer の更新バージョンをご覧ください。この答えはもはや有効ではなく、もはや機能しません。歴史的な理由でここに置いておきます。
この質問はかなり古いですが、 .getBoundingClientRect()
オブジェクトとそのwidth
およびheight
値の現在のサポートにより、このきちんとしたメソッドをtransform
と一緒に使用する機能と組み合わせて、私の解決策について言及する必要があると思います同じように。
実際にご覧ください here 。 (Chrome 42、FF 33および37でテスト済み。)
getBoundingClientRect
は、要素の実際のbox幅と高さを計算します。簡単に言えば、すべての要素をループし、そのmin-heightを子の実際のボックスの高さに設定できます。
$(".statusColumn").each(function() {
var $this = $(this),
child = $this.children(":first");
$this.css("minHeight", function() {
return child[0].getBoundingClientRect().height;
});
});
(いくつかの変更を行うと、子をループして、最も高い子を見つけて、親の高さを最も高い子に設定できます。しかし、この例はより簡単にすることにしました。必要に応じて高さ、またはCSSで関連するbox-sizing
値を使用できます。
ただし、CSSにtranslate
とtransform-Origin
を追加して、位置決めをより柔軟かつ正確にすることに注意してください。
transform: rotate(-90deg) translateX(-100%);
transform-Origin: top left;
書き込みモードプロパティがこれを行います。 writing-mode
の現在のサポートはまともです 。単純な回転と組み合わせると、正確な結果が得られます。以下の例を参照してください。
.statusColumn {
position: relative;
border: 1px solid #ccc;
padding: 2px;
margin: 2px;
width: 200px;
}
.statusColumn i,
.statusColumn b,
.statusColumn em,
.statusColumn strong {
writing-mode: vertical-rl;
transform: rotate(180deg);
white-space: nowrap;
display: inline-block;
overflow: visible;
}
<div class="container">
<div class="statusColumn"><span>Normal</span></div>
<div class="statusColumn"><a>Normal</a></div>
<div class="statusColumn"><b>Rotated</b></div>
<div class="statusColumn"><abbr>Normal</abbr></div>
</div>
( Bram Vanroy による回答から分割)