6

経験則 - レイアウトで CSS をいじりすぎている場合は、フレームワークに切り替えてください。私は数十のグリッド/レイアウト フレームワークを検討してきましたが、それらのほとんどは従来のドキュメント グリッド レイアウトに焦点を当てています。

私のページはどちらかというと SPA (シングル ページ アプリケーション) です。これは、デスクトップ アプリケーションで使用されるレイアウトに似ています。明らかに、HTML はこれをうまく処理できず、多くの CSS をいじる必要があります。

私が達成しようとしているレイアウトの例を次に示します (これは画面全体を埋める必要があります)。 ここに画像の説明を入力

固定メニューは、その背後にあるスクロール コンテンツの上に移動してはならないことに注意してください。各ブロックは独自の「フレーム」に存在する必要があります。つまり、左側の長いリストのスクロールバーは固定メニューの下に表示されます。

これをサポートする軽量のグリッド フレームワークを見つけることができませんでした (Sencha や Kendo UI のようなフレームワークは少し過剰です)。CSS を手動で行うのは非常に面倒です。特に、モーダル ダイアログ ボックスを表示することに決め、このダイアログ ボックス内に同様のレイアウトが必要な場合 (最終的に私を殺したのはこれです)。または、一番下に別の固定メニューが必要だと判断した場合、すべての地獄が解き放たれます.

これが CSS のみで可能かどうかさえわかりません (スクロールバーが重ならないように、その背後にあるコンテンツを縮小するために、少なくとも固定された下部メニューには CSS にハードコードされた値が必要であることはわかっています)。JS ソリューションが必要で、ブラウザ画面のサイズ変更イベントを処理する必要がある場合は、それを行う簡単な一般的なイベントがないため、再びすべての地獄が解き放たれます。

保守可能/柔軟な方法でこれにどのようにアプローチすればよいですか?

コメント: お気づきのとおり、HTML テーブルを使用してこのレイアウトを実装することを提案する回答を自分で追加しました。私は自分の答えを受け入れるつもりはありません。テーブルを提案するほど「勇敢」な人は誰もいないだろうと感じていました(結局のところ、それは物議を醸しています)、議論のために反対票を投じても構わないと思っていました

明確化:保守可能で柔軟性があると言うとき、私は十分に明確ではなかったようです。私が言いたいのは、さまざまなシナリオや必要な変更を伴うレイアウト処理を適切に (つまり、私の代わりにほとんど作業を行わずに) 行うことです。絶対に具体的にするために、いくつかの例を挙げましょう:

  1. レイアウトは、ページ全体として表示されるか、固定モーダル ダイアログ (つまり、ブートストラップ ダイアログ) 内に表示されるかを気にする必要はありません。これらのシナリオを切り替えても、レイアウト コードはできるだけ変更しないでください。

  2. レイアウトは、幅と高さ (つまり、サイド バーの幅またはトップ メニューの高さ) を記述するさまざまな方法をサポートする必要があります。具体的には、次のサイジング方法をサポートする必要があります。

    • 正確な固定ピクセル サイズ。
    • コンテナーのパーセンテージを使用した相対的なサイズ設定。例: サイド バーの幅は、コンテナー全体 (フル ページまたはダイアログ) の幅の 30% です。別の例: トップ メニューの高さは、コンテナー (フル ページまたはダイアログ) の全体の高さの 20% です。
    • 独自のコンテンツをラップします。例: トップ メニューの高さは、その中のコンテンツによって異なります。1 行のテキストを入力すると、スクロールせずに折り返されます。2 行のテキストを入力すると、2 倍の大きさになり、スクロールせずに保持されます。
    • ボーナス: 2 つの単純な組み合わせ。サイドバーの幅が 20% で、50 ピクセル以上あるようなものです。

Ian Clark が最も専門的に指摘したように、CSS はこれらの要求のほとんどをすぐに実現できます。それについての議論はありません。未加工の CSS が最も使いやすいかどうか、フレームワークやフレックスボックスやテーブルなどの別のメカニズムによって開発者からオフロードできるものがあるかどうかという疑問が残ります。

4

9 に答える 9

8

更新 2 (この質問は進化しているようです!):

基準 1 - フル ページまたはモーダル内の切り替えでは、コードをできるだけ変更しないでください

この場合、私たちの幅/高さbodyは常に幅/高さの 100% であるためwindow、コードをモーダルなどに簡単に適応させたい場合は、常に を使用できます。position:absoluteコンテキストがなければ、これはbody.

基準 2 - レイアウトは、幅と高さを表すさまざまな方法をサポートする必要があります

これは、あなたが言及したほとんどすべてを実行できる JSFiddleです。固定要素では、パーセンテージ幅と固定ピクセル幅の両方を使用します。最初に注意すべきことは、私がしなければならなかった唯一の変更は、box-sizing:border-box各要素に a を追加したことです。flexbox とは異なり、これは IE8 までさかのぼってサポートされているため、問題が発生することはありません。これを追加すると、幅を変更して補正することなく、要素にパディングを追加できます。

左サイドバーの幅は 20% ですが、最小幅は 100 ピクセルです。右側のメイン コンテンツとの重複を防ぐために、いくつかの単純なロジックを使用して逆を確立します。

Reaches Min At = Min-width / Width * 100

したがって、この例では、左側のサイドバーは で 1 分に達し100/20*100 = 500pxます。次に、@mediaセレクターを使用して、このウィンドウ サイズに達したときにメイン コンテンツの幅を変更します。

@media(max-width:500px) {
  #scrolling-content { 
    left:100px;
  }
}

フィドルでウィンドウ サイズを変更すると、最小サイズに達するとメイン コンテンツ エリアの色が変わることに気付くでしょう。わかりにくいかもしれませんが、Less などの言語を使用すると、widthmin-widthsを変数として簡単に設定でき、単純な関数を使用して CSS を変更できます。「ほぼすべて」というフレーズを使用した理由は、モーダルで同様のことをしたい場合、これがはるかに複雑になる可能性があるためです。

ちょっとしたこと: JavaScript を使用してサイズ変更イベントを取得する場合は、必要以上に何百回も計算を行いたくないため、 jQuery のデバウンスされたサイズ変更プラグインを検討してください。ほとんどはまだ関連性があり、開発中の質問に歴史的に正確であるため、この回答に余分なコンテンツを残します


更新: フレックスボックスの使用を提案する回答はたくさんありますが、現時点ではそれが優れたソリューションだとは思いません。誤解しないでほしいのですが、 FlexBoxが本当に実行可能な解決策であるならば、私はそれを望んでいます。他の JavaScript ソリューションを使用している可能性が高く、JavaScript がページのプレゼンテーション全体に使用する適切なツールではないと思います。

シンプルな CSS を使用して目標を達成するのが難しい理由はまだわかりませんposition。JavaScript を使用する必要はありません。私はそれ非常に扱いやすいと主張します。スタイルシートの維持に本当に苦労している場合は、Sass/SCSSLessなどを使用してみてください。変数、ミックスイン、関数などを作成して、必要な変更の数を大幅に減らすことができます。


そうは言っても、彼は純粋な CSS と HTML だけを使用して作業する、ソリューションの非常に簡単なモックアップです。私が使用しているのは 4 つの固定divs だけです。「スクロールするコンテンツ」が固定されないように簡単な変更を加えることができますが、マージンを使用して正しく配置するだけです。これには、div 内でスクロールする必要がなく、本体に対してスクロールできるという追加のボーナスがあります。

必要なすべての CSS:

div { position:fixed; }
#top {
    top:0;
    left:0;
    right:0;
    height:40px;
}

#menu {
    top:40px;
    height:40px;
    left:0;
    width:200px;
}

#long-list {
    top:80px;
    left:0;
    width:200px;
    bottom:0;
    overflow-y:auto;
}
#scrolling-content {
    top:40px;
    bottom:0;
    right:0;
    left:200px;
    overflow-y:auto;
}

メニューの高さと幅として40pxとの繰り返しを簡単に確認できます。200pxそれを念頭に置いて、動的言語の変数を使用して、それらを 1 回だけ定義することができます (少ない例)。

@leftwidth: 200px;

#scrolling-content {
    left:@leftwidth;
}
#menu, #longlist {
    width:@leftwidth;
}

論争 #1: フレームワークは柔軟性がなく、編集も容易ではない

静的コンテンツに依存しているため、CSS フレームワークを簡単に操作するのは難しいとおっしゃいました。 4,6)。しかし、Bootstrap 2 では、列の数を非常に簡単にカスタマイズできます。この機能は、Bootstrap 3 RC2 が登場したときにも存在することを期待してください。Bootstrap で Lessを使用できるリソースも多数あります。とは言っても、Less スタイルの柔軟な流体グリッド システムを作成することはかなり日常的です。デモを参照してください(免責事項: 私は Less の経験がありません。この記事はループに役立ちました)。

/* The total number of columns you wish to use */
@columns: 15;
/* 
    We loop through and for each create class
   .dynamic-<index>-<columns> 
*/
 .looping (@index) when (@index > 0) {
    (~".dynamic-@{index}-@{columns}") {
        width: percentage(@index/@columns);
    }
    .looping(@index - 1);
}
/* Stop and do nothing at 0 */
.looping (0) {}
/* Call our function */
.looping (@columns);

そして、HTML マークアップは単純に次のようになります。

<div class="cf rows">
    <div class="dynamic-4-15">4/15th width</div>
    <div class="dynamic-7-15">7/15th width</div>
</div>

論争 #2: CSS を使用した割合ベースのモーダルは難しい

あなたが言及したコメントでは、「レイアウトをブラウザウィンドウの幅ではなく、ダイアログの幅に相対的にしたい」と述べました。それも確かに可能です。実際、これは非常に簡単で、コードをほとんど変更する必要はありません

#some-modal {
   position:fixed;
   top:10%;
   bottom:10%;
   left:10%;
   right:10%;
}
/* Before this was simply div, and it was fixed, now it's absolute */
#some-modal div {
   position:absolute;
   padding:10px;
}
于 2013-08-04T16:03:55.573 に答える
1

ストレートで最小限の CSS でこれを行うことができ、完全に柔軟になります (ユーザーがフォント サイズを変更したり、コンテンツの長さが不明であっても問題ありません)。

http://codepen.io/cimmanon/pen/vusmz

このマークアップを想定すると:

<header>Header</header>

<div class="container">
  <div class="sidebar">
    <aside>Menu (fixed)</aside>
    <nav>long list</nav>
  </div>
  <main>
    <p>...</p>
  </main>
</div>

CSS:

body, html {
  height: 100%;
  max-height: 100%;
  margin: 0;
  padding: 0;
}

body {
  display: -ms-flexbox;
  display: -webkit-flex;
  -webkit-flex-direction: column;
  -ms-flex-direction: column;
  flex-direction: column;
}
@supports (flex-wrap: wrap) {
  body {
    display: flex;
  }
}

.container {
  display: -ms-flexbox;
  display: -webkit-flex;
  -webkit-flex-flow: column wrap;
  -ms-flex-flow: column wrap;
  flex-flow: column wrap;
  -webkit-flex: 1;
  -ms-flex: 1;
  flex: 1;
}
@supports (flex-wrap: wrap) {
  .container {
    display: flex;
  }
}

.sidebar {
  display: -ms-flexbox;
  display: -webkit-flex;
  -webkit-flex-direction: column;
  -ms-flex-direction: column;
  flex-direction: column;
  -webkit-flex: 1 100%;
  -ms-flex: 1 100%;
  flex: 1 100%;
}
@supports (flex-wrap: wrap) {
  .sidebar {
    display: flex;
  }
}

header {
  background: yellow;
  height: 3em; /* optional */
}

aside {
  background: green;
  height: 4em; /* optional */
}

nav {
  background: orange;
  -webkit-flex: 1;
  -ms-flex: 1;
  flex: 1;
  overflow-y: scroll;
  height: 1px;
}

main {
  background: grey;
  -webkit-flex: 1;
  -ms-flex: 1;
  flex: 1;
  overflow-y: scroll;
  height: 1px;
}

ブラウザーのサポートは、サポートの要件により制限されていますflex-wrap: wrap(IE10 は、それをサポートする「部分的なサポート」を提供する唯一のブラウザーです: http://caniuse.com/#feat=flexbox )。現在のブラウザのサポートは、Chrome、Opera、IE10、および Blackberry 10 に限定されています。

スクロール要素の高さが非常に小さいことに注意してください。これにより、Flexbox が完全にサポートされていないブラウザーでは問題が発生する可能性があります (詳細については、NEWER flexbox api を使用したフルハイト アプリでの Flexbox と垂直スクロールを参照してください)。

于 2013-08-06T02:06:15.357 に答える
0

カスケード フレームワークを調べて、このテンプレートをレイアウトの出発点として使用することをお勧めします。

ここに画像の説明を入力

于 2016-01-14T02:19:39.763 に答える
0

いくつかのプロジェクトでは、次のようなコードを使用してそれを行いました(FFでテスト済み):

<style>
#topMenu {
    position: fixed;
    left: 0px;
    top: 0px;
    width: 100%;
    height: 100px;
}
#sidePanel {
    position: fixed;
    left: 0px;
    top: 100px;    
    width: 100px;
}
#sideMenu {
    width: 100%;
    height: 50px;
}
#sideList {
    border-width: 0px;
    width: 100%;
    padding: 0px;
    margin: 0px;
    background-color: #FFF0F0;
}
#content {
    border-width: 0px;
    padding: 0px;
    margin: 0px;
    background-color: #F0FFF0;
}
body {
    border-width: 0px;
    padding: 100px 0px 0px 100px;
    margin: 0px;
}
</style>

<div id="topMenu">Top menu</div>
<div id="sidePanel">
    <div id="sideMenu">Size menu</div>
    <iframe id="sideList"></iframe>
</div>    
<iframe id="content"></iframe>

<script>
function onResize() {

    var sizePanel = document.getElementById("sidePanel");
    sizePanel.style.height = (document.documentElement.clientHeight - 100) + "px";   
    document.getElementById("sideList").style.height = (sizePanel.clientHeight - 50) + "px";   

    var content = document.getElementById("content");
    content.style.width = (document.documentElement.clientWidth - 100 - 10) + "px";
    content.style.height = (document.documentElement.clientHeight - 100 - 10) + "px";
}

window.addEventListener("resize", onResize);
onResize();

</script>
于 2013-07-30T10:13:59.193 に答える
0

特にフレームワークに慣れておらず、問題を抱えている場合は、フレームワークを使用する必要はないと思います。さまざまなビューをoverflow:scrollに設定するだけで、その画像で説明したものを作成できるはずです. 他にできることは、Javadocのように各ビューに iframe を設定することです。

于 2013-08-05T08:16:56.860 に答える
-1

開示:私はOPであり、一般的な反応を得るためのアイデアを投げかけています.

TABLESを使用できるため、専用のフレームワークは必要ありません。

はい、私は<table> <tr> <td>レイアウトのために広く避けられている領域について話しています。レイアウトのためにテーブルを避けるべきであることはよく知られています。ここに記載されている理由を調べてみました: HTML のレイアウトにテーブルを使用しないのはなぜですか?

この場合、ほとんどの理由が有効ではないように思えます (SPA):

レイアウトからのコンテンツの分離- SPA は実際にはコンテンツではない (AJAX で埋められたデータを含むスケルトンにすぎない) ため、この引数は適用されません。これは単なるインターフェースです。Google がインデックスに登録することは期待していません。

テーブルの保守性は低くなります- この場合はそうではありません。これを div で実装するために経験しなければならない CSS 地獄は、はるかに保守しにくいものです。

テーブルはレンダリングに時間がかかります- もちろん、レンダリングにより多くの計算を必要とする複雑なレイアウトが必要です。通常、JS のサイズ変更イベントで補正します。ブラウザーがレンダリング エンジン内でネイティブにこれを行うことは、非常に効率的です。

于 2013-07-31T07:34:16.340 に答える