简体   繁体   中英

How to fill remaining height and width?

I'm an experienced .net developer, but all of us have areas where we can benefit from improvements. I feel that I'm severely lacking in HTML/CSS skills and I'm trying to teach myself in this area.

I'm trying to create an HTML layout for an application that monitors bandwidth consumption on the local network. I envisage the layout as consisting of 4 elements:

+--------------------------+
+ Controls                 +
+--------+-----------------+
+ Legend +  Graph          +
+        +                 +
+        +                 +
+        +                 +
+        +                 +
+--------+-----------------+
+ Log                      +
+--------------------------+
  • Controls - this is a narrow area that will allow clear, pause and otherwise control the graph. It will also allow to show and hide log area. This means that the layout need to accommodate the log area being hidden.
  • Legend - is a table that will list all series on the graph. It will show series color and also some numeric data associated with the series. If there are more lines in the legend that fit the screen it should be possible to vertical scroll legend area. Horizontal scroll is never required for the area it's assumed that it is always narrow enough. The height of Legend (and Graph) should take up all the remaining space that is not used by Control area and Log area. The width of the legend will be equal to the natural table width .
  • Graph - there will be a Graph here painted over HTML canvas . This should take up all available space both horizontally and vertically.
  • Log - here will be two or three lines of log displayed. If there are more than 3 lines to display there should be a vertical scroll bar on this area. This area need to be able to be hid-able. The height of this area can be made fixed. (in the vicinity of 100px - 200px ).

The layout should adapt to window re-sizing, and keep looking descent when windows is being made small (to a point of course). Unless the window is too small, it should not have outer horizontal and vertical scrollbars.

Unfortunately, I cannot get it right in several places.

This is my code:

<html>
  <head>
    <style>
      * {margin:0;padding:0;height:100%;}
      html, button, input, select, textarea {
          font-family: sans-serif;
          font-weight: 100;
          letter-spacing: 0.01em;
      }
      .container {
        min-height:100%;
        position:relative;
      }
      .control {
          background:green;
          width:100%;
          height:auto;
          margin-top: 0;
      }
      .content {
        width:100%;
        margin:0;
        margin-top:0;
        margin-bottom:0;
      }
      .legend {
        position:relative;
        background:blue;
        float:left
      }
      .graph {
        background:red;

      }
      .log {
        background:yellow;
        width:100%;
        height:auto;
        position:absolute;
        margin-top: 0;
        margin-bottom: 0;
        bottom:0;
        left:0;
      }
      .table {
          border-collapse: collapse;
          border-spacing: 0;
          empty-cells: show;
          border: 1px solid #cbcbcb;
      }
      .table td,
      .table th {
          border-left: 1px solid #cbcbcb;
          border-width: 0 0 0 1px;
          font-size: inherit;
          margin: 0;
          overflow: visible;
          padding: 0.5em 1em; 
      }
      .table thead {
          background-color: #e0e0e0;
          color: #000;
          text-align: left;
          vertical-align: bottom;
      }
      .table td {
          background-color: transparent;
      }
      .table-odd td {
          background-color: #f2f2f2;
      }
    </style>  
  </head>
  <body>
    <div class="container">
      <div class="control">header1<br/>header2</div>
      <div class="content">
        <div class="legend">
          <table class="table">
              <thead>
                  <tr>
                      <th>#</th>
                      <th>Make</th>
                      <th>Model</th>
                      <th>Year</th>
                  </tr>
              </thead>
              <tbody>
                  <tr class="table-odd">
                      <td style="background-color: #FFB300">1</td>
                      <td>Honda</td>
                      <td>Accord</td>
                      <td>2009</td>
                  </tr>

                  <tr>
                      <td style="background-color: #803E75">2</td>
                      <td>Toyota</td>
                      <td>Camry</td>
                      <td>2012</td>
                  </tr>

                  <tr class="table-odd">
                      <td style="background-color: #FF6800">3</td>
                      <td>Hyundai</td>
                      <td>Elantra</td>
                      <td>2010</td>
                  </tr>

                  <tr>
                      <td style="background-color: #A6BDD7">4</td>
                      <td>Ford</td>
                      <td>Focus</td>
                      <td>2008</td>
                  </tr>

                  <tr class="table-odd">
                      <td style="background-color: #C10020">5</td>
                      <td>Nissan</td>
                      <td>Sentra</td>
                      <td>2011</td>
                  </tr>

                  <tr>
                      <td style="background-color: #CEA262">6</td>
                      <td>BMW</td>
                      <td>M3</td>
                      <td>2009</td>
                  </tr>

                  <tr class="table-odd">
                      <td style="background-color: #817066">7</td>
                      <td>Honda</td>
                      <td>Civic</td>
                      <td>2010</td>
                  </tr>

                  <tr>
                      <td style="background-color: #007D34">8</td>
                      <td>Kia</td>
                      <td>Soul</td>
                      <td>2010</td>
                  </tr>
              </tbody>
          </table>
        </div>
        <div class="graph"><canvas></canvas></div>
      </div>  
      <div class="log">log1<br/>log2</div>
    </div>
    <script>
      function resize() {
        var canvas = document.querySelector('canvas');
        canvas.style.width = '100%';
        canvas.style.height = '100%';
        canvas.width = canvas.offsetWidth;
        canvas.height = canvas.offsetHeight;
        ctx = canvas.getContext('2d');
        ctx.strokeStyle='yellow';
        ctx.beginPath();
        ctx.moveTo(0,0);
        ctx.lineTo(canvas.width,canvas.height);
        ctx.stroke();
        }
      resize();
      window.addEventListener('resize', resize, false);
    </script>
  </body>
</html>

This is the corresponding JSFiddle

Particular problems that I'm facing:

  • Why canvas is being rendered outside of the enclosing div ? This is very surprising to me and I cannot figure out why.
  • How do I make the table be spaced out naturally? In particular:
    • Why first line is so tall?
    • How do I make the table do not take the whole height ? It's enclosing dive that has height:100% , not the table, so why is it so tall?
    • How do I make it scroll-able if it's does not fit in the height ?
  • The Legend/Graph area seems to extend underneath the Log area. Why? How do I prevent that?
  • Finally, how can I make the Log area of fixed height and scroll-able?

My apologies, I know that this question is a tall order, I'll gratefully accept any help and/or pointers. I do realize that I lack basic understanding, but that's what I'm trying to work against. I spent most of the evening today researching this topic and looking for source that allowed me to put together at least this non-working example. I'm comfortable with JavaScript, it's HTML/CSS that I mainly need help with. I studied the documentation on what properties of different DOM objects do, but it's difficult to figure out what properties to use and how.

You are complicating your CSS a lot for what you want,

you can use CSS Flexbox along with CSS calc() for this

 body { margin: 0 } section { background: red; height: 50px; } article { display: flex; height: calc(100vh - 100px) } aside, div { background: lightblue; } aside { overflow-y: auto; max-width: 45% } aside ~ div { flex: 1 } canvas { width: 100%; height: 100%; background: green } .table { display: table; table-layout:fixed; width:100% } .row { display: table-row; background-color: #fff; } .column { display: table-cell; vertical-align: top; border-left: 1px solid #cbcbcb; border-width: 0 0 0 1px; font-size: inherit; margin: 0; padding: 0.5em 1em; background-color: inherit; } .cell-header { font-weight: bold; } .row-odd { background-color: #f2f2f2; }
 <main> <section>Controls</section> <article> <aside> <div class="table"> <div class="row row-odd"> <div class="column cell-header">#</div> <div class="column cell-header">Make</div> <div class="column cell-header">Model</div> <div class="column cell-header">Year</div> </div> <div class="row"> <div class="column" style="background-color: #FFB300">1</div> <div class="column">Honda</div> <div class="column">Accord</div> <div class="column">2009</div> </div> <div class="row row-odd"> <div class="column" style="background-color: #803E75">2</div> <div class="column">Toyota</div> <div class="column">Camry</div> <div class="column">2012</div> </div> <div class="row"> <div class="column" style="background-color: #FF6800">3</div> <div class="column">Hyundai</div> <div class="column">Elantra</div> <div class="column">2010</div> </div> <div class="row row-odd"> <div class="column" style="background-color: #A6BDD7">4</div> <div class="column">Ford</div> <div class="column">Focus</div> <div class="column">2008</div> </div> <div class="row"> <div class="column" style="background-color: #C10020">5</div> <div class="column">Nissan</div> <div class="column">Sentra</div> <div class="column">2011</div> </div> <div class="row row-odd"> <div class="column" style="background-color: #CEA262">6</div> <div class="column">BMW</div> <div class="column">M3</div> <div class="column">2009</div> </div> <div class="row"> <div class="column" style="background-color: #817066">7</div> <div class="column">Honda</div> <div class="column">Civic</div> <div class="column">2010</div> </div> <div class="row row-odd"> <div class="column" style="background-color: #007D34">8</div> <div class="column">Kia</div> <div class="column">Soul</div> <div class="column">2010</div> </div> </div> </aside> <div> <canvas width="985" height="223"></canvas> </div> </article> <section>Log</section> </main>

Well your code is a mess. Here is my attempt to clean it a bit and achieve what you described: https://jsfiddle.net/dckex2g7/

I assumed that top and bottom bars have fixed height which makes this a bit simpler. If they don't, you should use display: flex; flex-direction: column display: flex; flex-direction: column on body element and flex-grow: 1 on .content.

Notice how I haven't used any JS for layout. To make it responsive you should use things like min-width and media queries. You almost never need JS for layout unless in a very few very specific cases which are not covered by flexbox somehow.

There's really a lot to describe about this solution so if you have any specific question ask away.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM