web-dev-qa-db-ja.com

CSSトランジションが高さのパーセンテージに対して機能していませんか?

次のCSS定義があります。

.detailsCollapsed
{
   display:none;
   height:0%;
   width:100%;
   -webkit-transition:height 40s ease-in-out;
}

.detailsExpanded
{
    display:block;
    visibility:visible;
    height:100%;
    width:100%;
    -webkit-transition:height 40s ease-in-out;
}

これらは、中にいくつかのコンテンツがあるdivに適用されます。

また、divをクリックすると、要素のクラス名が変更されるjavascriptがあります。これは、展開および折りたたみには正常に機能しますが、iPhoneにアニメーションはありませんか? (他のすべてのトランジションは、滑らかなアニメーションでうまく動作しようとしました)何かアイデアはありますか?

44
Patrick

これまでの(純粋なCSS)ソリューション

height:auto;を終了し、max-heightの固定値を使用すると、遷移をシミュレートできます。

.details-expanded {
    max-height: 300px; /* try to guess a max-height for your content */
}

.details-collapsed {
    height: auto;
    max-height: 0;
    transition: max-height 500ms linear; /* pick a proportional duration */
}

要素が展開されるときの遷移期間とmax-heightに注意してください。目的の動作が得られるまで、値を試してください。

この方法では、2つの定義された値(上記の例では0から300)の間の遷移を取得できますが、heightプロパティはmax-height遷移に「追従」し、コンテンツのサイズ。


デモ

DEMO 1 -このソリューションの実用例

DEMO 2 -DEMO 1で行われていることのデモのみ


観察

今のところ、遷移は事前定義された値の間でのみ実装されており、エンジンが場合によっては初期値または最終値を推測できないためだと思われます。最終値が50%の高さ遷移があるが、遷移自体が何らかの形で親の高さに影響する場合はどうでしょうか。おそらく、各フレームで複数の reflow が必要になるため、パフォーマンスの問題が発生します。

fabb said と同様に、CSSトランジションの仕様により、パーセンテージ値をサポートする必要があることが決定されているため、エンジンが動的に評価されたポイントを使用して遷移をサポートするケースを決定するまでの時間。それでも、autoの値が考えられる場合の正しい動作とは何であるかについてはわかりません。

64
kbtzr

CSS3トランジションのW3C仕様 によると、lengthpercentageは、プロパティの遷移heightに許可される必要があります。したがって、ブラウザで割合を指定できるようになるのは時間の問題だと思います。

16
fabb

私は同じ問題を抱えていました。トランジションは「折りたたみ」のときは正常に機能しましたが、「表示:なし」が前に設定されていた場合、「エキスパンド」ではトランジションなし(「スイッチオン」など)で表示されました。

デバッグ中に誤って実際のソリューションに到達しました。「offsetHeight」を照会するだけで、要素の内部再レンダリングが強制されるようです。

このようなもの:

    showElement = function(){
       ...
       oEl.style.display = "block";
       var xDump = oEl.offsetHeight;
       oEl.className = "show";
    }

xDumpは決して使用されませんが、それを使用することで違いが生じました。

3
DDTech

Display noneとblockを切り替え、遷移効果を維持する必要がある要素には、次のソリューションを使用しました。

function slidedown(element) {
    ...
    element.style.display = "block";
    var timerId = setTimeout(function(){
        element.style.webkitTransitionProperty = "height";
        element.style.webkitTransitionTiming = "linear";
        element.style.webkitTransitionDuration = "3.5s";
        element.style.height = "500px";
    }, 0);
    ...
}

setTimeout関数は、ディスプレイプロパティを切り替えた後、遷移が発生するのを許可する短い遅延を強制します。それが役に立てば幸い。

2
Christian

遷移を停止しているのは、display:noneからdisplay:blockへの変更です。折りたたみスタイルをdisplay:blockに設定してみてください。高さ:0;オーバーフロー:非表示;

注:autoの拡張された高さも遷移を停止します。包含ブロックに高さが設定されていない場合、100%の高さはautoの高さに等しくなります。

1
Nicholas

うまくいけば、あなたはすでにこれを回避していますが、私は同じ問題に出くわしたと言っているだけです:WebKitは、少なくともiOS 4.1では、「display:none」スタイルの要素で定義されたトランジションをアニメーション化しません; "、上記のニコラスと同じです。

私の場合のように、この要素をレンダリングしないことの懸念がパフォーマンスである場合、高さを0に設定することとは別の解決策を提案します。あなたのボディのonLoadイベントコールバックで、要素を変数に保存し、DOMから削除します。それを表示するときが来たら、それを再挿入します。

0
Adrian Ghizaru

ここにパーセンテージを使用したい人のためのソリューションがあります。

トリックは、設定された高さと幅を持つdiv内にそれを含めることです。コンテナdivをフローティングしている場合、これは理想的ではないかもしれませんが、コンテナを絶対に配置する場合、要素が互いにオーバーラップしない限り、これはかなりうまく機能するはずです。

ここにコードがあります

.container {
    width: 500px; 
    height: 500px; 
    background: transparent;
}
.expand-content{
    height: 0%; 
    color: #fff;
    background: green;
}
.expand-content:hover {
    height: 100%; 
    background: orange;
    transition: all 2s ease;
}
.expand-content p  {
    font-size: 35px; 
    text-align: center;     
}
<div class="container">
    <div class="expand-content">
        <p>Expanded Content</p>
    </div>
</div>

jSFiddleで: http://jsfiddle.net/jtZ8j/7/

0
JCBrown

最大高さを計算する必要のないCSSソリューション

全高がわからない場合の解決策は次のとおりです

.container{
  
  overflow:hidden;
  max-height:20px;
  transition-property: max-height;
  -webkit-transition-property: max-height;
  transition-delay: 1s; /*Set a delay for this css-propery so content also slides up*/
  -webkit-transition-delay: 1s;
}
.container .content{
  z-index:5;
  background-color:LightGray;
  
  margin-top:20px;
  transform:translateY(-100%);
  -webkit-transform:translateY(-100%);
  transition:transform 1s;
  -webkit-transition:transform 1s;
}
.container:hover{
  max-height:9999px; /*apparently "none" doesnt work*/
  transition-delay: 0s;
  -webkit-transition-delay: 0s;
}
.container:hover .content{
  
  transform:translateY(0);
  -webkit-transform:translateY(0);
}

/*Less interesting stuff below*/
body{
  background-color:navy;
}
div,label{
  margin:0;
  padding:0;
}
.container label{ /*Just a label to describe what you can do here*/
  height:20px;
  line-height:20px;
  display:block;
  z-index:10;
  position:absolute;
  background-color:maroon;
  width:100%;  
}
<body>
<div class="container">
<label>
Hover container
</label>
<div class="content">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras venenatis congue lectus pharetra interdum. Cras sit amet interdum ipsum, vel commodo ante. Maecenas quis libero eu tortor suscipit rutrum. Cras quam eros, malesuada ac semper sed, viverra condimentum nisl. Quisque lobortis porta purus non fringilla. Fusce erat eros, aliquam a diam quis, ullamcorper laoreet odio. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum pharetra scelerisque felis, vitae finibus dui lobortis non. Mauris iaculis rutrum vehicula. Nullam porta arcu et diam porta, in tristique nisl ornare. Mauris id ex maximus, lobortis erat a, laoreet justo.

Nullam tempus neque enim, nec consectetur enim fringilla ac. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Proin non rutrum nisl, sed vestibulum augue. Sed ac magna et metus tempus bibendum elementum id libero. Sed semper imperdiet risus et pellentesque. Aliquam commodo magna at rhoncus pellentesque. Vivamus tempus tellus lorem, a volutpat est pharetra nec. Vestibulum velit ligula, aliquet sit amet bibendum eget, viverra scelerisque tellus. Cras aliquam hendrerit bibendum. Etiam non faucibus nisi, sit amet cursus neque. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.

Maecenas in eros ac elit pretium molestie. Mauris quis dolor erat. Suspendisse scelerisque gravida libero, rutrum consectetur metus ultrices in. Fusce eleifend, orci vitae sodales dictum, lectus nunc volutpat nulla, in efficitur dolor augue sed lorem. Nam ac lectus ultrices, ornare magna non, auctor neque. Mauris eros eros, bibendum commodo dolor non, posuere ultrices leo. Nullam ut laoreet ligula. Nulla posuere risus nec nibh fermentum, pretium consequat tellus eleifend. Vestibulum volutpat nisl quis euismod pulvinar. Donec hendrerit augue sed dui volutpat ultrices. Pellentesque mollis scelerisque metus, vulputate viverra risus pellentesque et. Duis nisi ante, faucibus in nunc et, semper varius turpis. Vivamus pharetra volutpat convallis.

Curabitur quis urna in orci tincidunt cursus vel ac dolor. Integer turpis augue, maximus eu lectus a, euismod consequat risus. Fusce leo lacus, dignissim vel sapien at, venenatis porttitor dui. Donec in metus non ex facilisis venenatis. In ac urna non tellus lobortis fringilla. Maecenas ornare dui nisl, gravida ornare purus aliquam in. Cras nec tortor eget neque volutpat pulvinar. In vestibulum, ante ut pharetra semper, nulla libero tincidunt nunc, a convallis orci dolor vel metus. Vivamus enim est, volutpat sit amet sagittis ut, efficitur at lacus. Morbi laoreet erat sit amet finibus finibus. Nulla sodales ut est non commodo. Aliquam sed purus a magna vehicula ullamcorper et id nunc. Curabitur aliquet tempor odio, euismod tempor ante consectetur ut. Proin neque sem, imperdiet sed est quis, ultricies tincidunt sem.

Donec nec sem id eros congue convallis eu in nibh. Etiam viverra sollicitudin maximus. In hac habitasse platea dictumst. Ut quis porta turpis. Duis egestas quam diam, id bibendum dolor imperdiet quis. Praesent ac odio in neque ultrices commodo. Nullam ac lacus sit amet dolor rhoncus tincidunt.
</div>
</div>
</body>

実施例

0