Good CSS practices for responsive Height. Is it armengue or not?

Asked

Viewed 5,104 times

8

I made this code that leaves the height responsive, it adjusts according to the size of the viewport. (Rotate the snippet and resize the screen).

whereas the html and the body have a height: 100%, I built a basic skeleton with 3 divs and I was distributing this height:100% between them (as you can see in the snippet). After that, I gave a position:absolute for each div and a top according to the size of each.

Well, how do you attribute the top for each div in hand, I got the feeling that this can be an armengue, because if there are more divs, I’ll have to make that calculation for the topagain. I think there are better ways to do this...

So, in what other ways can I do it? This way I did, can be considered an armengue?

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

.div1{
	position: absolute;
	width: 100%;
	height: 10%;
	background: red;
}

.div2{
	position: absolute;
	top: 10%;
	width: 100%;
	height: 75%;
	background: green;
}

.div3{
	position: absolute;
	top: 85%;
	width: 100%;
	height: 15%;
	background: yellow;
}
<div class="principal">
	<div class="div1"></div>
	<div class="div2"></div>
	<div class="div3"></div>
</div>

  • 1

    I updated the answer, please test the first two examples, should solve, let me know anything ;)

2 answers

11


Look "there is no" this thing of good practice, there are better ways yes, but not every good practice meets everything.

Now the only thing I say you should avoid is making entire layout based on position: absolute;, That’s quite expensive.

Note: What you really want isn’t necessarily responsive

Apparently the goal is simple and dismisses position, change height for min-height and so should the content be greater it will adjust:

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

.principal {
    height: 100%;
}

.div1{
    height: 10%;
    background: red;
}

.div2{
    min-height: 75%;
    background: green;
}

.div3{
    height: 15%;
    background: yellow;
}
<div class="principal">
    <div class="div1">a</div>
    <div class="div2">b</div>
    <div class="div3">c</div>
</div>

I used min-height only in the div2 which is where the content goes, but if you need to adjust the others you can change the other attributes height for min-height, see the result with much content:

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

.principal {
    height: 100%;
}

.div1{
    height: 10%;
    background: red;
}

.div2{
    min-height: 75%;
    background: green;
}

.div3{
    height: 15%;
    background: yellow;
}
<div class="principal">
    <div class="div1">a</div>
    <div class="div2">
         b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br>
         b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br>
         b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br>
         b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br>
         b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br>
         b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br>
         b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br>
         b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br>
         b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br>
         b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br>
         b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br>
         b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br>
         b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br> b <br>
    </div>
    <div class="div3">c</div>
</div>

However this is not very responsive and is complicated to fix a height per pixels for example, so if you need see the next (display: flex, display: table) suggestions


Using display: flex

In case I would say that the best would be to use display: flex, this would be a functional example:

html,body {
    margin: 0;
    padding: 0;
    height: 100%;
}
body > .section {
   min-height: 100%;
}
.section {
    padding: 5px;
    box-sizing: border-box;
}
.header {
    padding: 5px;
    box-sizing: border-box;
    border: 2px #f00 solid;
    max-height: 46px;
}
.contents {
    border: 2px #fc0 solid;
}

.contents, .section {
    display: -webkit-flex;
    display: flex;
    flex-direction: column;
}

.header, .contents, .section {
    -webkit-flex: 1;  /* Safari 6.1+ */
        -ms-flex: 1;  /* IE 10 */
            flex: 1;
}
<div class="section">
    <div class="header">
        navbar, etc
    </div>
    <div class="contents">
        <h1>Teste</h1>

        <div class="section">
            <div class="header">
                navbar, etc
            </div>
            <div class="contents">
                <h1>Teste</h1>
            </div>
        </div>

    </div>
</div>

But the problem is that it is not supported by all browsers, see the support list on canIUse:

  1. Safari 6, Safari iOS6: Only supports old flexbox specification and does not support flex-wrap.
  2. IE 10 Mobile: Supports only syntax 2012
  3. IE 10 and IE 11 Partial support and features several bugs
  4. IE 8, IE 9 and Opera Mobile 12 do not support flex
  5. In Safari (it may have been fixed already) the height of the flex-free child elements in a flex element cannot work with percentage, however it works normally in other browsers.

Using display: table

As an alternative to the flex that works would be interesting to use display: table, however this is more used as a "hack" and the intended functioning of the display: table actually would be more to achieve effects like tabular data.

The display: table also displays behavior that will limit or affect other elements, so it can not be used the pie and right

Important note: use display: table alone can cause various unexpected behaviors (actually expected for the tables), which will directly affect the content and will make it very difficult to work the layout, leading you to have to create other tricks in an attempt to fix this, so to avoid this kind of situation always use table-row and table-cell.

An example with

html, body{
    margin: 0;
    padding: 0;
    height: 100%;
}
.section {
    width: 100%;
    height: 100%;
    border: 5px #00f solid;
    display: table;
    box-sizing: border-box;
}
.row {
    border: 5px #f00 solid;
    display: table-row;
}
.cell {
    display: table-cell;
}
.header {
    padding: 5px;
    box-sizing: border-box;
    border: 5px #000 solid;
    height: 46px;
}
.footer {
    padding: 5px;
    box-sizing: border-box;
    border: 5px #000 solid;
    height: 46px;
}
.contents {
    border: 5px #fc0 solid;
    height: 100%;
}
<div class="section">
    <div class="row">
        <div class="cell header">
        header
        </div>
    </div>
    <div class="row">
        <div class="cell contents">

            <div class="section">
                <div class="row">
                    <div class="cell header">
                    header
                    </div>
                </div>
                <div class="row">
                    <div class="cell contents">
                    contents
                    </div>
                </div>
                <div class="row">
                    <div class="cell footer">
                    footer
                    </div>
                </div>
            </div>

        </div>
    </div>
    <div class="row">
        <div class="cell footer">
        footer
        </div>
    </div>
</div>


Final note

There is no magic path or specific rule, you define how you want and this will also vary from browser support, but I say one thing from my point of view, using height 100% can even look beautiful on a screen of 15 and 17 inches, but larger screens may cause a strange blank effect, taking out the main footer of the site (which would be nice to fix on the "bottom") and background I would recommend that you not worry about making the content 100% tall, something like this would be enough:

html, body{
    margin: 0;
    padding: 0;
    height: 100%;
}
body > .main {
    position: relative;
    min-height: 100%;
}
body > .main > .footer {
    position: absolute;
    bottom: 0;
    left: 0;
    width: 100%;
    background: #fc0;
}
.footer .content {
    padding: 15px;
}
<div class="main">
    <div class="section">
        <h1>teste</h1>
    </div>
    <div class="footer">
        <div class="content">teste</div>
    </div>
</div>

  • 1

    Exact William, use the position:absolute and go adjusting the heights in the big hand besides not being the ideal mode, it takes a lot more work to adjust each item. Even with the EI incompatibility problem, the ideal solution that requires less adjustments is to use the Flex. I will research more about its features. Thank you very much for your help!

  • 1

    Yes, but where I wrote "Final note" can be a factor that can help you, it will depend on the project as well :)

3

You can optimize by doing this way:

html,
body {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
}
section {
  position: relative;
  display: table;
  height: 100%;
  width: 100%;
}
section div {
  float: left;
  width: 100%;
}
section div:first-child {
  height: 10%;
  background: red;
}
section div:nth-child(2) {
  height: 75%;
  background: green;
}
section div:last-child {
  height: 15%;
  background: yellow;
}
<section>
  <div></div>
  <div></div>
  <div></div>
</section>

  • A good example, just an addendum, use only the display: table; may cause unexpected effects on the content.

  • Certainly @Guilhermenascimento, I did only the basic optimization of the code already posted.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.