I'm designing my CSS layout, but can't get the div to stretch to 100% of the height of the parent.
I have a menu bar that takes up the top 13.714vh of the screen. Then I have a main div that I want to take up the remainder of the screen height which I did with height: 100%. bottom-container takes up the bottom 38.2% of the vertical space available in main, and I want speech-bubble to take up the remaining 61.8% of the vertical space in main.
For some reason though, there's a huge white container in the middle of the screen, and speech-bubble isn't taking up the remaining space because of it. Can anyone help me figure out what's going on?
Is there a problem with my HTML or did I make an error in the CSS?
Here's the code pen:
https://codepen.io/TheNomadicAspie/pen/NWjKwxE
body {
margin: 0;
}
.menu-bar {
height: 13.714vh;
width: 100vw;
background: darkblue;
top: 0%;
}
.main {
background: black;
grid-template-rows: 61.8% 100%;
height: 100%;
width: 100%;
padding-left: 1.5%;
padding-right: 1.5%;
padding-top: 1.5%;
padding-right: 1.5%;
}
.speech-bubble {
grid-row: 1;
position: relative;
background: orange;
height: 97%;
width: 97%;
border-radius: 4em;
}
.speech-bubble:after {
content: '';
position: absolute;
bottom: 0;
left: 50%;
width: 0;
height: 0;
border: 4em solid transparent;
border-top-color: white;
border-bottom: 0;
margin-left: -4em;
margin-bottom: -4em;
}
.email-container {
visibility: hidden;
}
.question-text {
visibility: hidden;
}
.bottom-container {
grid-row: 2;
position: fixed;
background: green;
height: 38.2%;
width: 100vw;
bottom: 0%;
left: 0%;
}
<div id="menu_bar" , class="menu-bar"></div>
<div id="main" , class="main">
<div id="speech_bubble" , class="speech-bubble">
<div id="email_container" class="email-container">
<label for="email">Enter your email:</label>
<input type="email" id="email" name="email">
<button id="submit_email_btn" class="btn">Submit</button>
</div>
<div id="question_text" class="question-text">Question</div>
</div>
</div>
<div id="bottom_container" , class="bottom-container">
</div>
</div>
</div>
Do you want anything like this? screenshot.
If so, making your .menu-bar as position: relative and modifying your .main class styles as follows will work:
.main {
position: absolute;
background: black;
left: 0;
right: 0;
height: 50%;
}
Also, you may add margin: auto in your speech-bubble class to align it to center.
Your main tag is not taking full height as your html and body tags are not taking the full height.
Always remember that block elements can stretch maximum to their's parent's height, hence you need to give html and body tag height of 100%.
I have added the additional css below.
html, body { height: 100%;}
I think you want thing like this
* {
margin: 0;
box-sizing: border-box;
}
body {
display: flex;
flex-direction: column;
height: 100vh;
}
.menu-bar {
height: 13.714vh;
background-color: tomato;
color: #fff
}
.main {
background: black;
padding: 1.5%;
flex: 1
}
.speech-bubble {
background-color: orange;
border-radius: 4em;
height: 95%;
position: relative;
display: flex;
flex-direction: column;
}
.speech-bubble:after {
content: '';
position: absolute;
bottom: 0;
left: 50%;
width: 0;
height: 0;
border: 4em solid transparent;
border-top-color: white;
border-bottom: 0;
margin-left: -4em;
margin-bottom: -4em;
}
.email-container {
align-items: center;
justify-content: center;
flex: 1;
display: flex;
}
.question-text {
height: 50px;
position: relative;
text-align: center
}
.bottom-container {
height: 70px;
background-color: lightseagreen;
}
Related
I am trying to understand the position in html and css by playing around with an example I have made up. In this example what I have created 3 divs which show color blocks. I am trying to make the first 2 blocks span the width of the screen and the third do just sit as it is on screen. I am trying to have all 3 blocks just stacked on top of each other.
in my html i have created 3 classes:
<div class="color-stripred">
</div>
<div class="color-stripblue">
</div>
<div class="color-stripgreen">
</div>
In my css i have defined the colors, shapes and positions of these blocks:
.color-stripred {
display: block;
height: 20px;
width: 100%;
background-color: red;
position: static;
top: 0;
left: 0;
}
.color-stripblue {
display: block;
height: 20px;
width: 100%;
background-color: blue;
left: 0;
}
.color-stripgreen {
display: block;
height: 20px;
width: 100%;
background-color: green;
left: 0;
}
The red block is on top followed by blue then green. It looks like the following picture:
The problem comes when I try and change the positioning in order to make red and box span the width of the screen. i change the red box css as follows:
.color-stripred {
display: block;
height: 20px;
width: 100%;
background-color: red;
position: fixed;
top: 0;
left: 0;
}
what happens is the redbox spans the width of the screen but the other two boxes shift upwards. how can i stop the blue box and the green box from shifting upwards?
The problem is caused by position: fixed; which you don't even need.
I think what you actually want is to set body { margin: 0; }.
According to W3Schools:
Most browsers will display the <body> element with the following
default values:
body {
display: block;
margin: 8px;
}
body:focus {
outline: none;
}
You can see in the snippet below, that if you add this to your CSS (i.e., remove the margin from the body), all three boxes become full viewport width (even though the width is set to 100%!).
See the snippet below.
body {
margin: 0;
}
.color-stripred {
display: block;
height: 20px;
width: 100%;
background-color: red;
top: 0;
left: 0;
}
.color-stripblue {
display: block;
height: 20px;
width: 100%;
background-color: blue;
left: 0;
}
.color-stripgreen {
display: block;
height: 20px;
width: 100%;
background-color: green;
left: 0;
}
<div class="color-stripred"></div>
<div class="color-stripblue"></div>
<div class="color-stripgreen"></div>
you could add margin-top:20px; to .color-stripblue
.color-stripred {
display: block;
height: 20px;
width: 100%;
background-color: red;
position: fixed;
top: 0;
left: 0;
}
.color-stripblue {
margin-top:20px;
display: block;
height: 20px;
width: 100%;
background-color: blue;
left: 0;
}
.color-stripgreen {
display: block;
height: 20px;
width: 100%;
background-color: green;
left: 0;
}
<div class="color-stripred">
</div>
<div class="color-stripblue">
</div>
<div class="color-stripgreen">
</div>
There is a block with header, body and footer parts inside of it. Header and footer heights are fixed, body height is determined by its content. I need the outer block size to be the size of its contents but not more then the size of its container. If the body height exceeds maximum possible size, then the y-scroll is shown for body, but header and footer stay at the top and bottom of outer block.
I made the FIDDLE. But I could only get as far as when I resize window the scroll appears for outer block, not for body block only.
This is CSS and HTML:
body, html {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
.container {
position: absolute;
top: 10px; bottom: 10px; left: 10px; width: 200px;
border: 1px solid red;
}
.innerContainer {
border: 1px solid purple;
max-height: 100%;
overflow: auto;
}
.header, .footer {
height: 30px;
background: blue;
}
.body {
background: green;
}
<div class='container'>
<div class='innerContainer'>
<div class='header'></div>
<div class='body'>text<br>text<br>...</div>
<div class='footer'></div>
</div>
</div>
Is it possible to do what I need without using JavaScript?
EDIT: I made an image to make it clear what I need.
Well Here is your code from what I understand that you want the header
sticks to top and footer in the bottom and you can scroll the body if
necessary in the container size.
<div class='container'>
<div class='innerContainer'>
<div class='header'></div>
<div class='body'>text<br>texttext<br>texttext<br>texttext<br>texttext<br>texttext<br>texttext<br>texttext<br>texttext<br>texttext<br>text
</div>
<div class='footer'></div>
</div>
</div>
We need to style the footer and header separately plus your style as you will see in the code below
So you add to .innerContainer (position: absolute; bottom: 0; right: 0; left: 0; height: 100%; overflow: hidden;) and for the .body you add(height: 50%; overflow-y: auto;)
body, html {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
.container {
position: absolute;
top: 10px; bottom: 10px; left: 10px; width: 200px;
border: 1px solid red;
}
.innerContainer {
border: 1px solid purple;
height: 100%;
max-height: 100%;
overflow: hidden;
bottom: 0;
top: 0;
right: 0;
left: 0;
position: absolute;
}
.header, .footer {
height: 30px;
background: blue;
}
.body {
background: green;
min-height: 20px;
max-height: 36%;
overflow-y: auto;
font-size: 20px;
}
I hope that what you want and if you have any question please let me know.
The only solution I've found is using CSS3 calc. Doesn't work in Android browswer, though... FIDDLE
body, html {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
.container {
position: absolute;
top: 10px; bottom: 10px; left: 10px; width: 200px;
border: 1px solid red;
overflow: hidden;
}
.header, .footer {
height: 30px;
background: blue;
}
.body {
height: 300px;
background: green;
}
.bodyContainer {
max-height: calc(100% - 60px);
overflow-y: auto;
}
<div class='container'>
<div class='header'></div>
<div class='bodyContainer'>
<div class='body'></div>
</div>
<div class='footer'></div>
</div>
I'm trying to create a navbar similar to youtube, where there is two divs that are each floated to the opposite sides of the screen. In the middle I'm trying to make a searchbar which expands to fill the remaining space. When the user resizes their browser, the searchbar's width should contract to allow for a responsive layout. I cannot for the life of me figure out how to do this. Whenever I am able to get the searchbar to be responsive, it causes the right floated div to be pushed underneath it, and wont start collapsing in on itself until it reaches the very edge of the screen. I want it to start collapsing as soon as it hits the right floated div.
Here is the html:
<header>
<nav id="page-nav-left" role="navigation"> </nav>
<form id="searchBar-form">
<input type="text" id="searchBar" placeholder="Search...">
</form>
<nav id="page-nav-right" role="navigation"> </nav>
</header>
The CSS is all in this fiddle: http://jsfiddle.net/L9qvpL32/
Perhaps something like this?
http://jsfiddle.net/L9qvpL32/2/
I just changed the order of your elements and changed some widths :)
If you don't want the search bar to change position just change to
#searchBar-form {
position: relative;
overflow: hidden;
min-width: 200px;
}
Is this what you're looking for? (You will need to refine it a bit to stop the search being hidden completely on smaller screens)
http://jsfiddle.net/zxctbynn/
<header>
<div class="left"></div>
<form id="searchBar-form" class="centre">
<input type="text" id="searchBar" placeholder="Search...">
</form>
<div class="right"></div>
</header>
header {
position: fixed;
top: 0px;
z-index: 300;
width: 100%;
height: 48px;
background-color: blue;
display: inline;
}
.left{
top: 0;
background-color: red;
width: 100px;
height:100%;
position: absolute;
}
.centre{
top: 0;
background-color: blue;
width: auto;
left: 100px;
right: 100px;
height:100%;
position: absolute;
padding: 0;
}
.centre input{
width: 100%;
}
header {
position: fixed;
top: 0px;
z-index: 300;
width: 100%;
height: 48px;
background-color: blue;
float:left;
}
form{
width:80%;
float:left;
}
#page-nav-left {
display: inline-block;
height: 100%;
width: 20%;
margin: 0 auto;
padding: 0px;
float: left;
background-color: red;
}
#page-nav-right {
display: inline-block;
height: 100%;
width: 20%;
margin: 0 auto;
padding: 0px;
float: left;
background-color: red;
}
#searchBar-form {
position: relative;
overflow: hidden;
width:60%;
}
#searchBar {
padding: 4px 15px;
background-color: white;
width: 100%;
}
#searchBar-button {
float: right;
padding: 4px 15px;
border: 0px solid #207cca;
color: black;
}
I am assuming this is what you want. You set your nav's in pixels. Always set width by % for responsiveness.
http://jsfiddle.net/L9qvpL32/1/
You should try to use flexbox. With flexbox you can float as many divs as you van in the same row, and they will be responsive to the parent and each other as well.
You also able to set, which element should fill the remaining space, and which elements width is fixed to an absolute value.
display: flex; ==> turns it the flexbox model
flex-grow: 0/1 (or other) ==> the current box can grow if there is remaining space
flex-shrink: 0/1 (or other) ==> the current box can shrink if there is less space then the elements width
You can find an amazing tutorial to flexbox here:
http://css-tricks.com/snippets/css/a-guide-to-flexbox/
header {
display: -webkit-flex;
display: flex;
position: fixed;
top: 0px;
z-index: 300;
width: 100%;
height: 48px;
background-color: blue;
}
#page-nav-left {
-webkit-flex-grow: 0;
flex-grow: 0;
-webkit-flex-shrink: 0;
flex-shrink: 0;
width: 100px;
background-color: red;
}
#page-nav-right {
-webkit-flex-grow: 0;
flex-grow: 0;
-webkit-flex-shrink: 0;
flex-shrink: 0;
width: 100px;
background-color: red;
}
#searchBar-form {
-webkit-flex-grow: 1;
flex-grow: 1;
-webkit-flex-shrink: 1;
flex-shrink: 1;
}
#searchBar {
width: 100%;
max-width: 400px;
}
#searchBar-button {
padding: 4px 15px;
border: 0px solid #207cca;
color: black;
}
<header>
<nav id="page-nav-left" role="navigation"> </nav>
<form id="searchBar-form">
<input type="text" id="searchBar" placeholder="Search...">
</form>
<nav id="page-nav-right" role="navigation"> </nav>
</header>
I am building a 3 columns layout website. The header will fixed on the top and nav will fixed on the left. Then the wrapper will contain main and aside. What I want is main and aside can fill the wrapper's height.
And here is my css. You can also see my jsFiddle http://jsfiddle.net/scarletsky/h8r2z/3/
* {
margin: 0;
padding: 0;
}
html, body {
width: 100%;
height: 100%;
}
.header {
width: 100%;
height: 100px;
position: fixed;
top: 0;
z-index: 9;
background: red;
}
.nav {
width: 20%;
height: 100%;
position: fixed;
top: 100px;
left: 0;
background: green;
}
.wrapper {
width: 80%;
min-height: 100%;
margin-top: 100px;
margin-left: 20%;
position: relative;
}
.main {
width: 70%;
min-height: 100%;
position: absolute;
left: 0;
background: black;
}
.aside {
width: 30%;
min-height: 100%;
position: absolute;
right: 0;
background: blue;
}
.u-color-white {
color: white;
}
It seems that they can work well. But when the content's height in main or aside more than their own height, it will not work. I don't know how to fix it.
Can anyone help me?
Thx!
You have a very strict layout. everything is fixed..
what if you need to change the header from 100px height to 120? you'll have to change it accordingly in a lot of different places.
This is a pure CSS solution for your layout, without fixing any height or width. (you can fix the height or width if you want to)
This layout is totally responsive, and cross browser.
if you don't fix the height/width of the elements, they will span exactly what they need.
Here's a Working Fiddle
HTML:
<header class="Header"></header>
<div class="HeightTaker">
<div class="Wrapper">
<nav class="Nav"></nav>
<div class="ContentArea">
<div class="Table">
<div class="Main"></div>
<div class="Aside"></div>
</div>
</div>
</div>
</div>
CSS:
* {
margin: 0;
padding: 0;
}
html, body {
width: 100%;
height: 100%;
}
body:before {
content:'';
height: 100%;
float: left;
}
.Header {
height: 100px;
/*No need to fix it*/
background-color: red;
}
.HeightTaker {
position: relative;
}
.HeightTaker:after {
content:'';
display: block;
clear: both;
}
.Wrapper {
position: absolute;
width: 100%;
height:100%;
}
.Nav {
height: 100%;
float: left;
background-color: green;
}
.ContentArea {
overflow: auto;
height: 100%;
}
.Table {
display: table;
width: 100%;
height: 100%;
}
.Main {
width: 70%;
/*No need to fix it*/
background-color: black;
display: table-cell;
}
.Aside {
width: 30%;
/*No need to fix it*/
background-color: black;
display: table-cell;
background-color: blue;
}
.u-color-white {
color: white;
}
This is a pretty common problem. I'd recommend either having a background image for wrapper that makes it appear like aside has a min-height of 100% or using the method on this site:
http://css-tricks.com/fluid-width-equal-height-columns/
just see this fiddle.... hope this is what you want...
.aside {
width: 30%;
min-height: 100%;
position:fixed;
right: 0;
background: blue;
}
http://jsfiddle.net/h8r2z/6/
I am currently working on a HTML5 and CSS project and am having a problem getting the containers to display properly.
What I want to have is a header bar at the top, a wrapper that contains 2 other divs and then a footer at the bottom which is always at the bottom of the window or at the bottom of the content whichever is further down.
Here's a snippet:
html, body
{
padding: 0;
margin: 0;
}
#wrapper
{
position: absolute;
background-color: purple;
height: 100%;
width: 100%;
margin-top: 0px;
}
header
{
position: absolute;
width: 100%;
height: 80px;
background-color: black;
color: white;
}
#articleContainer
{
background-color: blue;
width: 75%;
margin-left: auto;
margin-right: auto;
height: auto;
margin-top: 80px;
}
#articleContent
{
width: 70%;
background-color: yellow;
float: left;
}
#articleSideBar
{
position: relative;
width: 28%;
background-color: green;
float: right;
margin-left: 2px;
margin-right: 2px;
display: inline;
margin-top: 0px;
float: right;
height: auto;
}
<html>
<head>
<title>index</title>
<link href="ArticleStyleSheet.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="wrapper">
<header>
Header
</header>
<div id="articleContainer">
Article Container
<div id="articleContent">
The quick brown fox jumped over the lazy dogs back. All good men must come to the aid of the party
</div>
<div id="articleSidebar">
Article Sidebar
</div>
</div>
</div>
</body>
</html>
At the moment the articleContainer is only the height of however many lines there are. What I want to have is the formContainer to fill the rest of the screen, I've tried adding the height: 100%; attribute but then this feels the form container over the screen size. I.e. a vertical scrollbar appears which is about the same height as the header. How can I get the formContainer to fill the available screen space without the scroll bar. However, if the content is larger than the form container should expand to fill the extra space.
Thanks for any help you can provide.
If you really want a css3 solution the one you're looking for is setting height: calc(100% - 80px); on #articleContainer as demonstrated in this fiddle, however this will not work in all browsers.
Example using old flexbox model css:
html, body
{
padding: 0;
margin: 0;
height: 100%;
}
#wrapper
{
display: -webkit-box;
-webkit-box-orient: vertical;
min-height: 100%;
background-color: purple;
width: 100%;
margin-top: 0px;
}
header
{
width: 100%;
height: 80px;
background-color: black;
color: white;
}
#articleContainer {
width: 75%;
margin: auto;
background-color: blue;
display: -webkit-box;
-webkit-box-flex: 1;
}
#articleContent
{
width: 70%;
background-color: yellow;
}
#articleSideBar
{
position: relative;
width: 28%;
background-color: green;
margin-left: 2px;
margin-right: 2px;
display: inline;
margin-top: 0px;
height: auto;
}
same thing, but this time using new flexbox model
css
html, body
{
padding: 0;
margin: 0;
height: 100%;
}
#wrapper
{
display: -webkit-flex;
-webkit-flex-direction: column;
min-height: 100%;
background-color: purple;
width: 100%;
margin-top: 0px;
}
header
{
width: 100%;
height: 80px;
background-color: black;
color: white;
}
#articleContainer {
width: 75%;
margin: auto;
background-color: blue;
display: -webkit-flex;
-webkit-flex: 1;
}
#articleContent
{
width: 70%;
background-color: yellow;
}
#articleSideBar
{
position: relative;
width: 28%;
background-color: green;
margin-left: 2px;
margin-right: 2px;
display: inline;
margin-top: 0px;
height: auto;
}
version with only the paragraph in yellow
I've used this method before, the tricky part is getting the header and footer in the right location. Once you have that the rest should fall into place:
jsfiddle:
http://jsfiddle.net/Ug5JR/
css:
html, body { margin: 0; padding: 0; height: 100%; }
header {
position: relative;
display: block;
background: red;
height: 100px;
z-index: 1;
}
article {
display: block;
background: yellow;
min-height: 100%;
margin-top: -100px;
margin-bottom: -100px;
}
article section {
display: block;
padding-top: 100px;
padding-bottom: 100px;
overflow: hidden;
}
footer{
display: block;
background: blue;
height: 100px;
}
p:hover {
height: 4000px;
}
markup:
<header></header>
<article>
<section>
<p>Hover me and I'll push the content larger than the page</p>
</section>
</article>
<footer></footer>
The trick is to get the negative margins to absorb the space used by the header and footer, this causes the 100% calculation to correct itself. You can then use any internal element to counter the negative margins with padding or margin on top and bottom. So whilst your article element is pretty much 100% height of the page, your article > section element will appear the right height and lay it's children out correctly.