CSS stretching to 100% Height - html

I'm trying to accomplish something very simple. My poor rusty CSS skills do not help one bit.
This is want to achieve:
I cannot make it happen. If I use height: 100% it works when there isn't much text, but when I add a lot of Lorem Ipsum, the content div gets stretched and the left menu div doesn't scale with it.
I don't want to use JavaScript, just clean CSS if it's that's possible.
HTML:
<html>
<head>
<title>test</title>
<link rel="stylesheet" type="text/css" href="css/style.css">
</head>
<body>
<div id="header">Header</div>
<div id="menu">Menu</div>
<div id="content">Content (paste a lot of lorem ipsum here and menu doesn't stretch)</div>
</body>
</html>
CSS
body
{
margin: 0;
height: 100%;
background-color: gray;
}
#header
{
height: 50px;
background-color: white;
border: 1px solid black;
}
#menu
{
width: 225px;
float: left;
height: calc(100% - 50px);
background-color: white;
border: 1px solid black;
}
#content
{
overflow: auto;
background-color: white;
border: 1px solid black;
}

Flexbox can do that.
Codepen Demo
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
height: 100%;
}
body {
min-height: 100%;
display: flex;
flex-direction: column;
}
header {
height: 50px;
background: #bada55;
}
section {
display: flex;
flex: 1;
background: #c0ffee;
}
aside {
width: 150px;
background: darkgoldenrod;
}
main {
min-height: 100%;
/*height: 2000px;*/ /* uncomment this to see difference */
background: blue;
flex: 1;
}
<header></header>
<section>
<aside></aside>
<main></main>
</section>

try to give height relative to viewport height. vh
height:100vh;

Related

Horizontal Split with Text Below and Above the Split

I want to create a page which is split by a box above a horizontal line and one below the horizontal line. Just above and below the line I want to have a text. I came up with a solution with flex and 4 divs where I adjust the height of each div to around 30%-20%-20%-30%. However when going responsive this sometimes keeps the text crossing the horizontal line. I want to guarantee that the above text stays above and the below text stays below.
Here my solution is - https://codepen.io/tobwun/pen/VwWRGWY
body,
html {
height: 100%;
width: 100%;
}
.m {
display: flex;
flex-direction: column;
height: 100%;
width: 100%;
text-align: center;
color: white;
font-weight: bold;
font-size: 2em;
}
.d1 {
background-color: pink;
width: 100%;
height: 30%;
}
.d2 {
background-color: pink;
width: 100%;
height: 20%;
}
.d3 {
background-color: lightblue;
width: 100%;
height: 20%;
}
.d4 {
background-color: lightblue;
width: 100%;
height: 30%;
}
<body>
<div class="m">
<div class="d1">
</div>
<div class="d2">
ABOVE TEXT
</div>
<div class="d3">
</div>
<div class="d4">
BELOW TEXT
</div>
</div>
</body>
I was wondering if it would be possible with two divs and some padding? With the first one the text on the bottom and the second one the text on top.. If this by design is not recommended to be done with flexbox I am also open for another solution.
Thanks for any help!
Why not just use two elements, and use align-items and justify-content to place them as you want ?
body,
html {
height: 100%;
width: 100%;
}
.m {
display: flex;
flex-direction: column;
height: 100%;
width: 100%;
color: white;
font-weight: bold;
font-size: 2em;
text-align:center;
}
.top, .bottom{
width: 100%;
height: 50%;
display:flex;
justify-content:center;
}
.top {
background-color: pink;
align-items:flex-end;
padding-bottom:0.5em;
}
.bottom {
background-color: lightblue;
align-items:flex-start;
padding-top:0.5em;
}
<body>
<div class="m">
<div class="top">
ABOVE TEXT
</div>
<div class="bottom">
BELOW TEXT
</div>
</div>
</body>
Easiest way to solve this is to use position: absolute;.
top: 50%; will put the element below the vertical center line.
bottom: 50%; will put the element above the vertical center line.
body {
margin: 0;
min-height: 100vh;
}
.top-text {
position: absolute;
bottom: 50%;
}
.bottom-text {
position: absolute;
top: 50%;
}
.top-text,
.bottom-text {
left: 0;
right: 0;
}
/* for styling purpose only */
body {
background: linear-gradient(darkblue 0% 50%, darkred 50% 100%);
color: white
}
.top-text,
.bottom-text {
text-align: center;
font-size: 2em;
border: 1px solid white;
padding: 5px;
}
<div class="top-text">Top</div>
<div class="bottom-text">Bottom</div>

Text node background behavior when wrapping

I'm having problems with a behavior I have never seen before. I added the code because Stack Overflow is asking me to put it in my post but I would recommend you go on the Codepen to try it for yourself.
HTML:
<html>
<body>
<div class="card">
<div class="name">Testing and Testeronintendo</div>
<div class="star">X</div>
</div>
</body>
</html>
CSS:
body {
width: 200px;
margin: 0;
background: green;
border: 5px solid black;
height: 100vh;
}
.card {
padding: 10px;
max-width: 300px;
background: yellow;
display: flex;
justify-content: space-between;
}
.name {
background: red;
}
Here is an image with a hand drawn example of the behavior I expect/need: https://i.stack.imgur.com/2tWRH.png
Explanation: I don't want the red background to extend all the way to the X, I simply want it to wrap cleanly around the text of the div.
Just add the minimum content of width to your name class. As far as I know by reading your question I understand that you want to make the red background as it's needed.
body {
width: 200px;
margin: 0;
background: green;
border: 5px solid black;
height: 100vh;
}
.card {
padding: 10px;
max-width: 300px;
background: yellow;
display: flex;
justify-content: space-between;
}
.name {
background: red;
width: min-content;
padding: 4px;
}
<html>
<body>
<div class="card">
<div class="name">Testing and Testeronintendo</div>
<div class="star">X</div>
</div>
</body>
</html>

Why overflow-y may affect horizontal layout in flex?

Consider the following flex layout:
body {
margin: 0;
}
.container {
background: red;
color: white;
height: 100vh;
display: flex;
}
.left {
flex-grow: 1;
height: 100%;
padding: 1em;
}
.main-content {
background: blue;
height: 130%;
}
.right {
height: 100%;
}
.side-content-upper {
padding: 1em;
height: 50%;
}
.side-content-lower {
padding: 1em;
height: 60%;
background: black;
}
<div class="container">
<div class="left">
<div class="main-content">some some some some some some some some some some some some some some some some some some some some some</div>
</div>
<div class="right">
<div class="side-content-upper">more</div>
<div class="side-content-lower">more</div>
</div>
</div>
Since heights of .main-content and of .side-content-upper plus that of .side-content-lower are greater than 100%, we get vertical overflow. Now let's make the first column fit the screen height and scroll separately by adding box-sizing: border-box; overflow-y: scroll; (to make this more compact, I align unchanged CSS into single lines):
body { margin: 0; }
.container { background: red; color: white; height: 100vh; display: flex; }
.left {
flex-grow: 1;
height: 100%;
padding: 1em;
box-sizing: border-box;
overflow-y: scroll;
}
.main-content { background: blue; height: 130%; }
.right {
height: 100%;
}
.side-content-upper { padding: 1em; height: 50%; }
.side-content-lower { padding: 1em; height: 60%; background: black; }
<div class="container">
<div class="left">
<div class="main-content">some some some some some some some some some some some some some some some some some some some some some</div>
</div>
<div class="right">
<div class="side-content-upper">more</div>
<div class="side-content-lower">more</div>
</div>
</div>
Works fine, doesn't it? Let's now apply the same style to the .right container:
body { margin: 0; }
.container { background: red; color: white; height: 100vh; display: flex; }
.left {
flex-grow: 1;
height: 100%;
padding: 1em;
box-sizing: border-box;
overflow-y: scroll;
}
.main-content { background: blue; height: 130%; }
.right {
height: 100%;
box-sizing: border-box;
overflow-y: scroll;
}
.side-content-upper { padding: 1em; height: 50%; }
.side-content-lower { padding: 1em; height: 60%; background: black; }
<div class="container">
<div class="left">
<div class="main-content">some some some some some some some some some some some some some some some some some some some some some</div>
</div>
<div class="right">
<div class="side-content-upper">more</div>
<div class="side-content-lower">more</div>
</div>
</div>
If your screen resolution is not too high, you'll see what I'm not expecting: the right column not only fits height and gets vertical scroll, but also shrinks and gets horizontal scroll. Why is that? It doesn't seem just the width of the vertical scrollbar: switch overflow-y of .right from scroll to hidden and you again will get .right deformed. I'm puzzled how to reason about this. Just in case, here's what I see with hidden:
Here are two 'fixes' for what it's worth - I know you're looking for an explanation more than a solution but hopefully this will help explain by example. I'm not confident I can detail the intricacies of what is happening here but it is basically do with the way scroll bars interact with with the box model, and how flex handles dimensions. If anyone more knowledgeable can shed some light please chime in.
Give the right div it's own flex property:
body { margin: 0; }
.container { background: red; color: white; height: 100vh; display: flex; }
.left {
flex: 5;
height: 100%;
padding: 1em;
box-sizing: border-box;
overflow-y: scroll;
}
.main-content { background: blue; height: 130%; }
.right {
flex: 1;
height: 100%;
box-sizing: border-box;
overflow-y: scroll;
}
.side-content-upper { padding: 1em; height: 50%; }
.side-content-lower { padding: 1em; height: 60%; background: black; }
<div class="container">
<div class="left">
<div class="main-content">some some some some some some some some some some some some some some some some some some some some some</div>
</div>
<div class="right">
<div class="side-content-upper">more</div>
<div class="side-content-lower">more</div>
</div>
</div>
Give the .side-content-upper and .side-content-lower a box-sizing: border-box property.
body { margin: 0; }
.container {
background: red;
color: white;
height: 100vh;
display: flex;
}
.left {
flex: 1;
height: 100%;
padding: 1em;
box-sizing: border-box;
overflow-y: scroll;
}
.main-content { background: blue; height: 130%; }
.right {
height: 100%;
box-sizing: border-box;
overflow-y: scroll;
}
.side-content-upper { padding: 1em; box-sizing: border-box; height: 50%; width: 100%; }
.side-content-lower { padding: 1em; box-sizing: border-box; height: 60%; background: black; width: 100%;}
<div class="container">
<div class="left">
<div class="main-content">some some some some some some some some some some some some some some some some some some some some some</div>
</div>
<div class="right">
<div class="side-content-upper">more</div>
<div class="side-content-lower">more</div>
</div>
</div>
One final note: when you give overflow to both the left and right divs, the container loses its implicit overflow: auto which was spacing your elements for you. This was causing the shrink issue - if you add overflow-y: scroll back on the container in your last demo the elements will regain their original proportions.
can use java script to help you by available screen height
add jquery.js in first
<script type="text/javascript">
$(document).ready(function(){
var y = screen.availHeight;
$(".container").css('height',y +'px');
$(".left").css('height',y +'px');
$(".right").css('height',y +'px');
$(".main-content").css('height',(y * 1.3) +'px');
$(".side-content-upper").css('height',(y * .5)
+'px');
$(".side-content-lower").css('height',(y * .6)
+'px');
});
</script>
<style type="text/css">
body { margin: 0; }
.container{
background: red;
color: white;
display: flex;
flex-wrap:wrap;
}
.left {
flex-grow: 1;
padding: 1em;
box-sizing: border-box;
overflow-y:scroll;
}
.main-content{ background: blue;}
.right{box-sizing: border-box;overflow-y: scroll;}
.side-content-upper { padding: 1em; }
.side-content-lower { padding: 1em; background:
black; }
</style>

margin-right of <div> in <div> not being shown in flexbox layout

I would like to create a container div wrapping another div that scrolls and has an equal margin around all sides. The issue is the margin setting is not being reflected on the right side and the .inner div only scrolls to the end of the width setting.
I have read other posts and found it may be related to the way the width is being set but am unable to get the css quite right for my case.
<!DOCTYPE html>
<html>
<style>
body {
display: flex;
align-items: center;
justify-content: space-around;
}
.outer {
height: 600px;
overflow: scroll;
border: 1px solid red;
}
.inner {
min-width: 2500px;
min-height: 2500px;
margin: 12.5px;
background-color: green;
}
</style>
<body>
<div class='outer'>
<div class='inner'></div>
</div>
</body>
</html>
I've tried to use padding in .outer and also various width settings including calc(x% - ypx)
I would like to be able to set the width of the container .outer so that it is not 100% of the page.
Any help is much appreciated!
I have just added overflow:inherit in inner div css.
<!DOCTYPE html>
<html>
<style>
body {
display: flex;
align-items: center;
justify-content: space-around;
}
.outer {
height: 600px;
overflow: scroll;
border: 1px solid red;
}
.inner {
min-width: 2500px;
min-height: 2500px;
margin: 12.5px;
background-color: green;
overflow:inherit;
}
</style>
<body>
<div class='outer'>
<div class='inner'></div>
</div>
</body>
</html>
The inner element has a min-width greater than the available horizontal space provided by the container. I've removed this attribute. Please review the snippet below.
body {
display: flex;
align-items: center;
justify-content: space-around;
}
.outer {
height: 600px;
overflow: scroll;
border: 1px solid red;
width: 85%;
}
.inner {
min-height: 2500px;
margin: 12.5px;
background-color: green;
}
<div class='outer'>
<div class='inner'></div>
</div>
UPDATE
As pointed out by the OP, if a fixed width is used for the inner element, than as you scroll to the right, no right margin is displayed. I did a bit of a trick and faked a right-margin by setting a right-border on the inner element, as follows:
.outer {
height: 400px;
overflow: scroll;
border: 1px solid red;
width: 85%;
}
.inner {
min-width: 800px;
min-height: 360px;
margin: 12px;
background-color: green;
border-right: 12px solid white;
}
<div class='outer'>
<div class='inner'></div>
</div>
Setting .inner to display:inline-block achieves the desired behaviour.
<!DOCTYPE html>
<html>
<style>
body {
display: flex;
align-items: center;
justify-content: space-around;
}
.outer {
height: 600px;
overflow: scroll;
border: 1px solid red;
}
.inner {
display: inline-block;
min-width: 2500px;
min-height: 2500px;
margin: 12.5px;
background-color: green;
}
</style>
<body>
<div class='outer'>
<div class='inner'></div>
</div>
</body>
</html>

How do I achieve this simple boxes layout

I'm trying to create the following layout using only regular CSS display properties (block, inline..) not using flex or grid.
The top thing(bandeau) should have a height of 100px and horizontal margins that are 50px.
Both the left and right columns should have a width of 100px.
The footer thingy(pied) should have a height of 80px and horizontal margins of 75px.
body {
margin: 0;
padding: 0;
background: black;
min-height: 100%;
}
.bandeau {
height: 100px;
background: white;
margin: 0 50px;
}
.menuGauche {
width: 50px;
background: lightblue;
height: calc(100% - 80px);
margin: 0 0 80px 0;
position: absolute;
}
.ecran {
background: lightgreen;
width: calc(100% - 100px);
height: calc(100% - 80px);
position: absolute;
margin: 0 50px;
}
.menuDroite {
width: 50px;
background: lightblue;
height: calc(100% - 80px);
margin: 0 0 80px 0;
position: absolute;
left: calc(100% - 50px);
}
.pied {
height: 80px;
background: white;
margin: 0 75px;
width: 100%;
position: absolute;
bottom: 0;
}
<div class="bandeau"></div>
<div class="menuGauche"></div>
<div class="ecran"></div>
<div class="menuDroite"></div>
<div class="pied"></div>
When I am doing this kind of layout, I try to group them horizontally, so the two columns will be wrapped in another div. similar to this:
<!DOCTYPE html>
<html>
<head>
<style>
.main {
background-color: black;
}
.top {
margin: 0 50px;
height: 100px;
background-color: white;
}
.mid {
height: 500px;
background-color: green;
}
.left-col,
.right-col {
height: 100%;
width: 100px;
background-color: blue;
}
.left-col {
float: left;
}
.right-col {
float: right;
}
.bottom {
margin: 0 75px;
height: 80px;
background-color: white;
}
</style>
</head>
<body>
<div class="main">
<div class="top"></div>
<div class="mid">
<div class="left-col"> </div>
<div class="right-col"> </div>
</div>
<div class="bottom"> </div>
</div>
</body>
</html>
I've used float and assume a height for the middle section as it was not specified. Here is a plunk. Hope this helps!
As a beginner, you should avoid using absolute positionning and learn display , then float.
Nowdays display flex makes it easier.
You may also use tags which can be meaningfull for the contents they hold.
Here an example via flex:
html {
height: 100%;
}
body {
margin: 0;
padding: 0;
background: black;
min-height: 100%;
display: flex;
flex-direction: column;
}
main {
flex: 1;
display: flex;
}
.bandeau {
height: 100px;
background: white;
margin: 0 50px;
}
.menuGauche {
width: 50px;
background: lightblue;
}
.ecran {
background: lightgreen;
flex: 1;
}
.menuDroite {
width: 50px;
background: lightblue;
}
.pied {
height: 80px;
background: white;
margin: 0 75px;
}
<header class="bandeau"></header>
<main>
<div class="menuGauche"></div>
<div class="ecran">Play the snippet full page or play with:https://codepen.io/anon/pen/rJMrgz.</div>
<div class="menuDroite"></div>
</main>
<footer class="pied"></footer>
Here is a tutorial (among others) to start with : https://css-tricks.com/snippets/css/a-guide-to-flexbox/
( 101 advises : for french readers https://www.alsacreations.com/article/lire/53-guide-de-survie-du-positionnement-css.html )
You can use the display:table on some elements to achieve the result. so wrap your main content then display it as table.
html,
body {
height: 100%;
}
body{
margin: 0;
padding: 0;
background: black;
}
.bandeau{
height: 100px;
background: white;
margin: 0 50px;
}
.content-wrapper {
display: table;
height: calc(100% - 180px);
width: 100%;
}
.content-wrapper > div{
display:table-cell;
}
.menuGauche,
.menuDroite{
width: 100px;
background: lightblue;
}
.ecran{
background: lightgreen;
}
.pied{
height: 80px;
background: white;
margin: 0 75px;
}
<body>
<div class="bandeau"></div>
<div class="content-wrapper">
<div class="menuGauche"></div>
<div class="ecran"></div>
<div class="menuDroite"></div>
</div>
<div class="pied"></div>
</body>