2016-07-24 13 views
2

私は、ドラッグでサイズを変更できるフレックスボックスコンテナを持っています。そのコンテナがオーバーフローするのを防ぐには(あまりにも小さくなり、いくつかの項目を隠すことを始めます)、アンダーフロー(あまりにも大きくなって空白を表示する)しないようにしますか?フレックスコンテナがオーバーフローまたはアンダーフローするのを防ぐには?

次の例では、すべてのアイテムが高さ(最後のものを除く)が18pxに達した時点でコンテナの縮小が停止し、すべてのアイテムが最大高さに達したときに展開が停止されます(空白スペースは表示されません)。

const resizable = document.querySelector('.flex'); 
 
let startHeight = NaN; 
 
let startY = NaN; 
 

 
resizable.addEventListener('mousedown', e => { 
 
    startHeight = resizable.getBoundingClientRect().height; 
 
    startY = e.pageY; 
 
}); 
 

 
window.addEventListener('mousemove', e => { 
 
    if (isNaN(startY) || isNaN(startHeight)) { 
 
    return; 
 
    } 
 
    
 
    resizable.style.height = (startHeight + e.pageY - startY) + 'px'; 
 
}); 
 

 
window.addEventListener('mouseup',() => { 
 
    startHeight = startY = NaN; 
 
});
.flex { 
 
    display: flex; 
 
    flex-direction: column; 
 
    overflow: hidden; 
 
    border: 1px solid black; 
 
    cursor: ns-resize; 
 
    -webkit-user-select: none; 
 
    -moz-user-select: none; 
 
    -ms-user-select: none; 
 
    user-select: none; 
 
} 
 

 
.item-1 { 
 
    background: red; 
 
    height: 40px; 
 
    max-height: 60px; 
 
    flex: 1; 
 
} 
 

 
.item-2 { 
 
    background: blue; 
 
    flex: none; 
 
} 
 

 
.item-3 { 
 
    background: green; 
 
    height: 50px; 
 
    max-height: 50px; 
 
    flex: 1; 
 
} 
 

 
.item-4 { 
 
    background: yellow; 
 
    height: 30px; 
 
    flex: none; 
 
}
<div class="flex"> 
 
    <div class="item-1"> 
 
    Item 1 
 
    </div> 
 
    <div class="item-2"> 
 
    Item 2 
 
    </div> 
 
    <div class="item-3"> 
 
    Item 3 
 
    </div> 
 
    <div class="item-4"> 
 
    Item 4 
 
    </div> 
 
</div>

純粋CSS溶液が好ましいであろう。解決策は、すべてのアイテムが最小サイズになるようにコンテナを縮小し、すべてが最大サイズを占めるように拡大することです。 コンテナのCSSで最小と最大の高さをハードコードすることはできません。私は一般的な解決策を模索しています。

+0

を導入するときにも下の高さを計算することができます? http://isotope.metafizzy.co/ –

+1

私はそれについて知りませんでしたが、一見すると、それは石積みのようなレイアウトのライブラリのように見えますね。これでどのように問題を解決できるかについて詳しく説明できますか?ありがとう。 :) – matteodelabre

+0

フレックスで、 分の高さを設定してください:100px; 最大高さ:200ピクセル; もっと高度なものが必要な場合は、私が提案したライブラリを使用することができます:) –

答えて

1

JavaScriptを使用して絶対に高さを設定しているので、ここでは純粋なCSSソリューションはできないと思います。

私は以下のスニペットで行ったようにガードを追加することができます。サイズ変更可能なサイズは、あなたがこのライブラリを見たことがゼロであり、それは巨大だとするとき(DOMの変更と、おそらくより良いパフォーマンス悪い)それに基づいて境界

const resizable = document.querySelector('.flex'); 
 
const lastChild = resizable.querySelector(':last-child'); 
 
const resizableBorderBottom = 1; // hardcoded - could be computed too 
 
let startHeight = NaN; 
 
let startY = NaN; 
 

 
resizable.addEventListener('mousedown', e => { 
 
    /* 
 
    * here we assume that the bottom of the last child 
 
    * is the same as the bottom of the resizable for simplicity 
 
    */ 
 
    startHeight = resizable.getBoundingClientRect().height; 
 
    startY = e.pageY; 
 
}); 
 

 
window.addEventListener('mousemove', e => { 
 
    if (isNaN(startY) || isNaN(startHeight)) { 
 
    return; 
 
    } 
 
    const lastHeight = resizable.style.height; 
 
    resizable.style.height = ((startHeight + e.pageY - startY) | 0) + 'px'; 
 
    const lastChildBottom = lastChild.getBoundingClientRect().bottom | 0; 
 
    const resizableBottom = (resizable.getBoundingClientRect().bottom | 0) - resizableBorderBottom; 
 
    // check if we need to revert the change 
 
    if (lastChildBottom !== resizableBottom) { 
 
    resizable.style.height = lastHeight; 
 
    } 
 
}); 
 

 
window.addEventListener('mouseup',() => { 
 
    startHeight = startY = NaN; 
 
});
.flex { 
 
    display: flex; 
 
    flex-direction: column; 
 
    overflow: hidden; 
 
    border: 1px solid black; 
 
    cursor: ns-resize; 
 
    -webkit-user-select: none; 
 
    -moz-user-select: none; 
 
    -ms-user-select: none; 
 
    user-select: none; 
 
} 
 

 
.item-1 { 
 
    background: red; 
 
    height: 40px; 
 
    max-height: 60px; 
 
    flex: 1; 
 
} 
 

 
.item-2 { 
 
    background: blue; 
 
    flex: none; 
 
} 
 

 
.item-3 { 
 
    background: green; 
 
    height: 50px; 
 
    max-height: 50px; 
 
    flex: 1; 
 
} 
 

 
.item-4 { 
 
    background: yellow; 
 
    height: 30px; 
 
    flex: none; 
 
}
<div class="flex"> 
 
    <div class="item-1"> 
 
    Item 1 
 
    </div> 
 
    <div class="item-2"> 
 
    Item 2 
 
    </div> 
 
    <div class="item-3"> 
 
    Item 3 
 
    </div> 
 
    <div class="item-4"> 
 
    Item 4 
 
    </div> 
 
</div>

+0

最後の子供の立場をチェックすることは考えていませんでした。非常に巧妙な解決策。どうもありがとう! :) – matteodelabre

関連する問題