web-dev-qa-db-ja.com

transform:translateXを使用して、子要素を親全体で100%水平に移動する方法

すべて、

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 で確認できます):

enter image description here

私がすることができます:

#child {
    position: absolute;
    width: 20px;
    height: 100px;
    background-color:red;
    -webkit-transform: translateX(300px) translateX(-100%);
    transform: translateX(300px) translateX(-100%);
}

これは動作します( ここでもjsfiddleで )。これは、最初に子を300px(親の全幅)からマイナス20px(子の幅)移動するためです。ただし、これは固定の既知のピクセル寸法を持つ親に依存します。

enter image description here

ただし、レスポンシブデザインでは、親の幅がわからず、変更されます。

left:0right:0を使用できることは知っていますが、left/rightのアニメーションパフォーマンスはtranslateXよりもはるかに劣っています( Thanks Paul Irish! )。

これを行う方法はありますか?

前もって感謝します。

32
mattstuehler

追加の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>
28
vals

Flexboxを使用すると、この問題に対する非常に優れたソリューションがあります。重要なのは、flex-growプロパティを利用することです。

次のようなHTMLがあるとします。

<div class="flex-container">
  <div class="flex-spacer"></div>
  <div class="slider"></div>
</div>

まず、.flex-containerに基本的なdisplay:flexプロパティを指定し、そのflex-directionrowに設定します。子要素の位置をrelativeに設定して、.flex-container内で互いに隣接するようにします。

デフォルトでは、flex-growプロパティはに設定されています。これは最初に必要なものです。これは、.flex-spacerと.sliderが通常の寸法のみを持っていることを意味します。 .flex-spacerを空のままにしておくと、width of になります。

アニメーションに移りましょう。動作させるには、CSSルールが2つだけ必要です。transitionを.flex-spacerに追加し、flex-grow1 on .flexに設定します-イベント中のスペーサー。 2番目のルールは、.flex-container内の未使用のwidthを.flex-spacerのwidthに与え、最初のルールは幅の変化をアニメーション化します。 .slider要素は、.flex-containerのEdgeに沿ってプッシュされます。

CSSは次のようになります-.flex-spacerに背景を追加して、その存在をもう少し明確にし、ユーザーがホバリングするときにflex-grow1に設定します.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つ ペン がありますが、今回は入力のあるフォームのコンテキストでの例です。

10
Brady Lambert

(ユーザーバンのアプローチのように)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>

http://codepen.io/anon/pen/BLxYXO

3
Martin Cremer