CSS - 100% height / width issue - html

I need your help with:
html, body and #content have a height of 100% && #toolbar have a height of 50px and he is static => I need to calculate the height of #content to fill the content without scroll bar
#content > .a must have a width of 300px and #content > .b must calculate the width to fill the content
jsfiddle.net:
https://jsfiddle.net/4uesapnt/2/
https://jsfiddle.net/4uesapnt/2/embedded/result/

1) You can use the CSS3 calc() function (docs) and viewport units (vh, vw) (docs) for this.
#content {
height: calc(100vh-50px); /* substract #toolbar height from the entire page's height*/
}
2) Once again, you can use viewport units and the calc() function:
#content > .a {
width: 300px;
}
#content > .b {
width: calc(100vw-300px); /* substract #content .a's width from the entire page's width */
}
Here it is on JSFiddle: https://jsfiddle.net/hL7nxs6v/1/
Please note that if you resize the window to be less in width than 300px + some reasonable width for .b, the layout might break if there aren't any appropriate min-widths assigned.
Browser support for viewport units, calc function via Can I Use.

This appears to work for me in Chrome. I've never used flex before so I don't really know what the support is like:
https://jsfiddle.net/eeesrkjr/
I gave the #content a top padding to leave space for the header, and because of box-sizing:border-box; it doesn't force it over the 100% height. Then then header is absolutely positioned in that 50px space. I experimented briefly with getting the header inside #content so as not to have to absolutely position, but flex was doing weird things. Perhaps you could try that route if you have a better understanding of how those things interact.
HTML:
<div id="toolbar" class="flex aic jcsb">
<div class="a">A</div>
<div class="b">B</div>
<div class="c flex aic jcsb">
<div class="b">C</div>
<div class="c">D</div>
<div class="d">E</div>
</div>
</div>
<div id="content" class="flex">
<div class="a">A</div>
<div class="b">B</div>
</div>
Styles:
* {
box-sizing: border-box;
}
html, body {
height: 100%;
}
body {
background: #111;
font-family: "Helvetica Neue";
font-weight: 300;
}
#toolbar {
background: linear-gradient(#333, #222);
border-bottom: 1px solid #000;
color: #bbb;
height: 50px;
padding: 0 25px;
width:100%;
position:absolute;
top:0px;
}
#toolbar > .c > div {
margin: 0 12.5px;
}
.flex {
display: flex;
}
.flex.aic {
align-items: center;
}
.flex.jcsb {
justify-content: space-between;
}
.flex.fdc {
flex-direction: column;
}
#content {
color: #fff;
height: 100%;
padding-top:50px;
box-sizing:border-box;
}
#content > .a {
background: red;
width: 300px;
float:left;
}
#content > .b {
background: blue;
width:100%;
}

Related

Calculating margin-top value to occupy remaining height in fluid design

Basically, the container has both fluid height and width. Kindly consider the following:
<div class="container">
<span class="header">Hello!</span>
<div class="box"></div>
<div class="box"></div>
</div>
Both of the box divs take say 40% height each, assume I apply 15% height for the span element and the remaining 5% for its margin-top value. As expected it will not sum up to 100% of the container height since
margin-top is calculated based on the width as far as I know. How do I calculate the margin-top percentage value in this case so all elements including the margin would sum up to the full height of the container? here's my CSS Code, thanks in advance.
.container {
height: 80%;
width: 80%;
}
.header {
height: 15%;
display: inline-block;
margin-top: 5%; /*how to calculate this correctly*/
}
.box {
height: 40%;
}
I think you can easily obtain what you want by using flexbox and margin-top:auto on header:
body,html {
height:100%;
margin:0;
}
.container {
height: 80%;
width: 80%;
display:flex;
flex-direction:column;
border:1px solid;
box-sizing:border-box;
}
.header {
flex:0 0 15%;
background:red;
align-self: flex-start; /* To have same visual behavior as inline-block */
margin-top:auto /* this will do the trick*/
}
.box {
flex:0 0 40%;
background:yellow;
}
<div class="container">
<span class="header">Hello!</span>
<div class="box">a</div>
<div class="box">b</div>
</div>
I prefer flexbox solution by #Temani, but in case you need to support old version of browsers like IE that does not support flexbox.
You can just add an empty span before header or use pseudo css element and give it a 5% height, this will give you the same margin top effect you need even for old browsers.
html,
body{
height:100%;
}
.container {
display:inline-block;
height: 80%;
width: 80%;
background-color:red;
}
.container:before {
content:" ";
display:inline-block;
width:100%;
height:5%;
background-color:red
}
.header {
height: 15%;
width:100%;
display: inline-block;
background-color:blue
}
.box {
display:inline-block;
width:100%;
height: 40%;
background-color:green
}
<div class="container">
<span class="header">Hello!</span>
<div class="box">1</div>
<div class="box">2</div>
</div>

Why doesn't the wrapper wrap around the box?

I'm struggling with a problem which seems simple:
My code:
* {
font-family: tahoma;
}
body {
background: #333;
}
.wrapper {
padding: 10px;
background: white;
width: 100%;
}
.box {
margin-top: 40px;
width: 1100px;
height: 400px;
background: #aaa;
}
<div class="wrapper">
<div class="box">
box
</div>
</div>
The box contained in the wrapper has a fixed size, which might overflow the wrapper on small screens. Why doesn't the wrapper wrap around the box? How would I do that?
You can also check out the issue in this jsFiddle.
In order to make this work:
Remove width: 100% and add to the wrapper display: inline-block.
Doing so, will enable the wrapper to have as much width as needed to wrap around the box. Putting width: 100% restricts your wrapper to the width of the screen and in case of the box having a bigger with than that of the screen, it won't work.
If you do not want to have a horizontal scrollbar, especially on narrower screens use: box-sizing: border-box on the wrapper.
CSS:
.wrapper {
display: inline-block; /* Ensures that the box stays wrapped */
padding: 10px;
background: white;
box-sizing: border-box; /* Ensures that there won't be a horizontal scrollbar */
}
Here is a working version of your jsFiddle, with both the wrapping issue mended and the horizontal scrollbar abolished.
* {
font-family: tahoma;
}
body {
background: #333;
}
.wrapper {
box-sizing: border-box display: inline-block;
padding: 10px;
background: white;
}
.box {
position: relative;
margin-top: 40px;
height: 400px;
background: #aaa;
}
<div class="wrapper">
<div class="box">
box
</div>
</div>
For reference:
display: inline-block;
box-sizing: border-box;
Use display:inline-block on the wrapper to resize the container based on the content inside.
The div element by default has display:block; so you need to change its display.
You should remove width:100%; from .wrapper class, then you can make it display:inline-block; or display:table;
*{
font-family:tahoma;
}
body{
background:#333;
}
.wrapper
{
padding:10px;
background:white;
display:inline-block;
}
.box
{
margin-top:40px;
width:1100px;
height:400px;
background:#aaa;
}
<div class="wrapper">
<div class="box">
box
</div>
</div>
Your problem occurs, because HTML documents, by default, display all elements as display: block.
There are two ways to do it as our friends have mentioned before.
First one is to use inline-block value for the display property:
body{
display: inline-block;
}
The second way is to use max-width:
div.wrapper{
max-width: 100%;
/*we have set height property to auto to have coefficient between width & height*/
height: auto;
}
For more information visit these webpages:
inline-block
max-width
You can solve the problem by using the following css:
* {
font-family: tahoma;
}
body {
background: #333;
}
.wrapper {
padding: 10px;
background: white;
display: inline-block;
}
.box {
margin-top: 40px;
width: 1100px;
height: 400px;
background: #aaa;
}
<div class="wrapper">
<div class="box">
box
</div>
</div>
The only change is I have added display: inline-block to .wrapper element.
Why wrapper doesn't wrap around the child div
The problem is all html element has some default CSS styling which gets applied by the browser.
In this case div gets a default property of display: block; It is the same property that makes a default unstyled div to take up full available width of it's parent element.
As you can see with this: snapshot of chrome dev tools
*The css style highlighted in red rectangle is the default styling applied by the browser.
*The red underlined text tells us about the width of the element. The fading out signifies that value of that property is computed by the browser.
** While we are at it I want to point you to a different problem that you might have faced with the previous code and if the goal was to make the wrapper to wrap box at all times.
If the .box div would have width far less than that of the width of the browser then another problem may arise which I have shown in the code snippet bellow.
* {
font-family: tahoma;
}
body {
background: #333;
}
.wrapper {
padding: 10px;
background: white;
}
.box {
margin-top: 40px;
width: 100px;
height: 400px;
background: #aaa;
}
<div class="wrapper">
<div class="box">
box
</div>
</div>
As you can see the box tries to cling to a side of wrapper.
You can read more about display css property here: CSS display property || CSS-Tricks

Square div with fixed height using only CSS

Everything is in the title !
How can I do to make my div's width equals to its fixed height using CSS only ?
HTML Code
<div class="container">
<div class="square"></div>
</div>
CSS Code
.square{
height:80%;
}
I know I can do the opposite (fixed width) using
.square{
width : 20%;
padding-top:20%
}
because padding-top is relative the width of the container.
I also know I can do it using simple JQuery but don't want to use javascript.
Thanks,
Use vw unit :
.square {
background: #000;
width: 50vw;
height: 50vw;
}
<div class="square"></div>
You need to use Viewport-percentage lengths vw
.square {
background: #000;
width: 20vw;
height: 20vw;
}
<div class="square"></div>
It seems like you want your div to be inside a .container which can be any size. This is easy if the size of that .container is based on the viewport width. I've created an example, below, which shows a block of square divs 2x2 inside of a .container. The .container can be any size. It is important the height and width of the container be based on viewport width.
.container {
width: 90vw;
height: 90vw;
margin: 0 5vw;
}
.container > div {
width: 48%;
height: 48%;
margin: 1%;
display: inline-block;
}
.square1 {
background: #aaa;
}
.square2 {
background: #bbb;
}
.square3 {
background: #ccc;
}
.square4 {
background: #ddd;
}
<div class="container">
<div class="square1"></div><div class="square2"></div><div class="square3"></div><div class="square4"></div>
</div>
If you don't want to use vw, try this out.
https://jsfiddle.net/zofoeLyL/2/
CSS
.square{
width:20%;
position:relative;
background-color:#005f95;
}
.square:before {
display: block;
padding-top: 100%;
}
HTML
<div class="square">
</div>
That will make the height always equal to whatever width % you decide to use.

3 Stacked DIVs to fit screen height?

Trying to stack 3 DIVs vertically, so that the top DIV is 25% of screen height, middle is 50%, and bottom is 25%, but they seem to extend the screen and I end up having a scrollbar.
body,html {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
#top {
width: 100%;
height: 25%;
background: #464646;
}
#middle {
width: 100%;
padding: 15px 0 15px 0;
margin: 0 auto 0 auto;
min-width: 657px;
height: 50%;
text-align: center;
vertical-align:middle;
}
#bottom {
width: 100%;
padding: 15px 0 15px 0;
height: 25%;
background: #988056;
}
<div id="top"></div>
<div id="middle"><img src="logo.png"></div>
<div id="bottom"></div>
As Hashem mentions in a comment above, box-sizing: border-box is considered best practice nowadays. Add the following to your CSS and you should be good to go:
html {
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
Here is a good read-up for you.
That said, if you are working on an existing product and have lots of legacy code that would be broken if you did this, you need to work around the margins and paddings on your site sections, they add height, and that makes it all add up to more than 100%.
And if you are uncomfortable with that as well, look up flex-box layout. Only works in modern browsers though, so don't do it if you need old IE support.
This is due to the padding that you have added to middle and bottom divs.
The width and height styles always specify the width/height of textual area i.e. width/height of the "div's content" and they do NOT include the padding value. The padding is an extra space added apart from the width/height.
Try the following, and it should give you the desired results:
HTML:
<div id="top"></div>
<div id="middle"><img src="logo.png"></div>
<div id="bottom"></div>
CSS:
body,html {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
#top {
width: 100%;
height: 25%;
background: #464646;
}
#middle {
width: 100%;
margin: 0 auto 0 auto;
min-width: 657px;
height: 50%;
text-align: center;
vertical-align:middle;
}
#bottom {
width: 100%;
height: 25%;
background: #988056;
}
Working LIVE.
The CSS flexbox layout module is especially made to handle requirements like this.
You can use the flex-grow property:
The flex-grow property is a sub-property of the Flexible Box Layout module.
IT defines the ability for a flex item to grow if necessary. It accepts a unitless value that serves as a proportion. It dictates what amount of the available space inside the flex container the item should take up.
For example, if all items have flex-grow set to 1, every child will set to an equal size inside the container. If you were to give one of the children a value of 2, that child would take up twice as much space as the others.
*{
margin: 0;
padding: 0;
}
html,body {
height: 100%;
}
#container{
-webkit-display:flex;
-moz-display:flex;
-ms-display:flex;
display:flex;
-webkit-flex-direction:column;
-moz-flex-direction:column;
-ms-flex-direction:column;
flex-direction:column;
height:100%;
}
#top {
-webkit-flex:1;
-moz-flex:1;
-ms-flex:1;
flex:1;
background: #464646;
}
#middle {
-webkit-flex:2;
-moz-flex:2;
-ms-flex:2;
flex:2;
background:dodgerblue;
}
#bottom {
-webkit-flex:1;
-moz-flex:1;
-ms-flex:1;
flex:1;
background: #988056;
}
<div id="container">
<div id="top"></div>
<div id="middle"></div>
<div id="bottom"></div>
</div>
In this scenario, since you're concerned about screen height, you might want to investigate the 'vh' css rule.
For instance, if you wanted to stack your top, middle, and bottom evenly, you could do it with pure css:
#top, #bottom, #middle {
height: 32vh;
}
Or, as pertains to the question:
#top { height: 25vh; }
#middle { height: 50vh; }
#bottom { height 24vh; } /*24 vh so you have a little wiggle room*/
Examine here:
body { margin : 0; padding: 0}
div { border: #ccc solid 1px; }
#top { height: 25vh; }
#middle { height: 50vh; }
#bottom { height: 24vh; }
/*24 vh so you have a little wiggle room*/
<div id="top">top</div>
<div id="middle">middle</div>
<div id="bottom">bottom</div>

How to force parent div to expand by child div width/padding/margin/box?

I want to expand div parent with child div but I don't know if that's possible and how to do it.
I prepare a fiddle and included some code.
CSS
body {
background: gray;
}
div.page {
color: white;
background: black;
max-width: 72em;
margin: auto;
padding: 1em;
}
div.one {
background-color: red;
width: 40%;
}
div.two {
background-color: green;
width: 120%;
}
HTML
<body>
<div class="page">
<div class="one">One</div>
<div class="two">Two</div>
</div>
</body>
The key solution to your problem is to use display:inline-block;
HTML
body {
background: gray;
}
div.page {
color: white;
background: black;
margin: auto;
padding: 1em;
display:inline-block;
}
div.one {
background-color: red;
width: 10em;
display:inline-block;
}
div.two {
background-color: green;
width: 40em;
display:inline-block;
}
<div class="page">
<div class="one">One</div>
<div class="two">Two</div>
</div>
You cannot use % and expect box to overflow, else it never ends 100% turns 120%, but then 120% of 120%, becomes .. and so on. forget this idea, it cannot work.
Your CSS request is incoherent.
Beside, to see an element to grow wider than window, one of the parent must be able to behave this way, mostly , content overflow and remain visible. (html/body or parent)
as far as i know only:
display:
table
inline-table
table-row
table-cell
Can let container grow as much as content does.
Your problem is this:
div.two {
background-color: green;
width: 120%;
}
You are telling the child to be 120% the width of the parent, which is to say, the entire width plus 20% more. Make it 100% and you should get the expected result..