すべて、
translateX
を使用して、子要素をその親全体(つまり、左端から右端まで)で100%アニメーション化できるようにしたいと思います。
課題は、translateX
のパーセンテージが親ではなく要素自体を参照することです。
したがって、たとえば、私のhtmlが次のようになっている場合:
<div id="parent">
<div id="child">
</div>
そして私のCSSは次のようになります(ベンダープレフィックスは省略されました):
#parent {
position: relative;
width: 300px;
height: 100px;
background-color: black;
}
#child {
position: absolute;
width: 20px;
height: 100px;
background-color:red;
transform: translateX(100%);
}
これは機能しません-子は20px(それ自体の100%)だけを移動し、親全体を移動しません。 (これは jsfiddle で確認できます):
私がすることができます:
#child {
position: absolute;
width: 20px;
height: 100px;
background-color:red;
-webkit-transform: translateX(300px) translateX(-100%);
transform: translateX(300px) translateX(-100%);
}
これは動作します( ここでもjsfiddleで )。これは、最初に子を300px(親の全幅)からマイナス20px(子の幅)移動するためです。ただし、これは固定の既知のピクセル寸法を持つ親に依存します。
ただし、レスポンシブデザインでは、親の幅がわからず、変更されます。
left:0
とright:0
を使用できることは知っていますが、left/rightのアニメーションパフォーマンスはtranslateXよりもはるかに劣っています( Thanks Paul Irish! )。
これを行う方法はありますか?
前もって感謝します。
追加のHTMLレイヤーを作成する必要があるため、当初はアイデアを投稿しませんでした。今後のより良いソリューションを期待していました。
それは起こっていないので、コメントを説明します。私が意味したことはこれでした:
#parent {
position: relative;
width: 300px;
height: 100px;
background-color: black;
}
#wrapper {
position: absolute;
width: 100%;
height: 100px;
border: solid 1px green;
transition: all 1s;
}
#wrapper:hover {
-webkit-transform: translateX(100%);
transform: translateX(100%);
}
#child {
position: absolute;
width: 20px;
height: 100px;
background-color:red;
}
#wrapper:hover #child {
-webkit-transform: translateX(-100%);
transform: translateX(-100%);
}
ラッパーは親の幅の100%であるため、100%の変換は期待どおりに機能します。
あなたが述べたように、ラッパーは100%翻訳されていることに注意してください。しかし、あなたが本当に望んでいるのは、要素を100%移動することです-幅。これを実現するには、子を反対方向に100%変換する必要があります(これは子の幅に適用されます)。
修正:子はラッパーの移行プロパティを共有する必要があります。
#parent {
position: relative;
width: 300px;
height: 100px;
background-color: black;
}
#wrapper {
position: absolute;
width: 100%;
height: 100px;
border: solid 1px green;
transition: all 5s;
}
#wrapper:hover {
transform: translateX(100%);
}
#child {
position: absolute;
width: 50px;
height: 100px;
background-color:red;
transition: inherit;
}
#wrapper:hover #child {
transform: translateX(-100%);
}
<div id="parent">
<div id="wrapper">
<div id="child"></div>
</div>
</div>
Flexboxを使用すると、この問題に対する非常に優れたソリューションがあります。重要なのは、flex-growプロパティを利用することです。
次のようなHTMLがあるとします。
<div class="flex-container">
<div class="flex-spacer"></div>
<div class="slider"></div>
</div>
まず、.flex-containerに基本的なdisplay:flexプロパティを指定し、そのflex-directionをrowに設定します。子要素の位置をrelativeに設定して、.flex-container内で互いに隣接するようにします。
デフォルトでは、flex-growプロパティはに設定されています。これは最初に必要なものです。これは、.flex-spacerと.sliderが通常の寸法のみを持っていることを意味します。 .flex-spacerを空のままにしておくと、width of になります。
アニメーションに移りましょう。動作させるには、CSSルールが2つだけ必要です。transitionを.flex-spacerに追加し、flex-growを1 on .flexに設定します-イベント中のスペーサー。 2番目のルールは、.flex-container内の未使用のwidthを.flex-spacerのwidthに与え、最初のルールは幅の変化をアニメーション化します。 .slider要素は、.flex-containerのEdgeに沿ってプッシュされます。
CSSは次のようになります-.flex-spacerに背景を追加して、その存在をもう少し明確にし、ユーザーがホバリングするときにflex-growを1に設定します.flex-containerより:
body * {
box-sizing: border-box;
}
.flex-container {
cursor: pointer;
display: flex;
flex-flow: row nowrap;
width: 100%;
border: 2px solid #444;
border-radius: 3px;
}
.flex-spacer,
.slider {
flex-grow: 0;
position: relative;
}
.slider {
padding: 25px;
background-color: #0DD;
}
.flex-spacer {
background-color: #DDD;
transition: all .4s ease-out;
}
.flex-container:hover .flex-spacer {
flex-grow: 1;
}
<div class="flex-container">
<div class="flex-spacer"></div>
<div class="slider"></div>
</div>
Flexboxはこれもかなり設定可能にします。たとえば、代わりに.sliderを右から左に移動するとします。 .flex-containerのflex-directionプロパティをrow-reverseに切り替えるだけで完了です。
この pen で自由に遊んでください。
さまざまな種類のイベントのアニメーションが必要な場合、物事が少し複雑になる可能性があることに留意してください。たとえば、ユーザーが入力要素を入力するときにラベルをアニメーション化しようとすると、この問題に遭遇しました。動作させるにはもう少しHTMLとCSSが必要ですが(JSも使用しました)、コンセプトは同じです。
もう1つ ペン がありますが、今回は入力のあるフォームのコンテキストでの例です。
(ユーザーバンのアプローチのように)wrapper-solutionを使用する場合は、親の幅の100%ではなく1%を参照し、変換された値に100を掛けることをお勧めします。 。
たとえば、子要素を親要素の中心に変換する場合:
#wrapper {
position: absolute;
left: 0;
top: 0;
width: 1%;
overflow: visible;
transform: translateX(5000%);
}
#child {
transform: translateX(-50%);
}
html
<div id="parent">
<div id="wrapper">
<div id="child">
</div>
</div>
<a onclick="alert('im still clickable')">
click me
</a>
</div>