How to split the screen in 3 horizontal divs [duplicate] - html

This question already has answers here:
Fixed header, footer with scrollable content
(7 answers)
Closed 2 years ago.
I'm coding a website and i want to split a page in 3 different section:
one for the title+a button,
one for the content,
one for the text input.
.
The problem is that the divs don't fill the height and the width of the screen. The second div also need a scrollbar because of his content that can vary.
I'd like to resolve the problem with CSS, but everything is accepted
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Server Messaggistica</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div style="width:100vh; height: 100vh;">//container of the 3 divs
<div style="width:100%; height: 15%;">//div1
<h1>Bentornato utente</h1>
<button class=button>LOG OUT</button>
</div>
<hr>
<div style="width:100%; height: 70%; overflow-y: scroll; overflow-x: hidden;">//div2
//php content
</div>
<hr>
<div style="width:100%; height: 15%;">//div3
<textarea name="messaggio" rows="3" cols="100"></textarea>
</div>
</div>
</body>
</html>

You can do this with the vh unit in CSS, which allows you to specify the height of containers in relation to the height of the viewport.
body {
margin: 0;
}
.vh-15 {
min-height: 15vh;
}
.vh-70 {
min-height: 70vh;
}
/* for illustration */
.bg-red { background: red; }
.bg-green { background: green; }
.bg-blue { background: blue; }
div { color: white; }
<div class='vh-15 bg-red'> 1: 15% </div>
<div class='vh-70 bg-green'> 2: 70% </div>
<div class='vh-15 bg-blue'> 3: 15% </div>

I would solve this using flexbox. The flex children values are relative to each other. I've based mine out of 100. The numbers are arbitrary though. Instead of 70 and 15, you could use 700 and 150.
.container {
display: flex;
flex-direction: column;
min-height: 100vh;
}
.top,
.bottom {
flex: 15;
}
.middle {
flex: 70;
}
/******************
Presentational
******************/
.middle { background-color: green; }
.middle::after { content: '2: 70%'; }
.top { background-color: red; }
.top::after { content: '1: 15%'; }
.bottom { background-color: blue; }
.bottom::after { content: '3: 15%'; }
.container > div { position: relative; }
body { margin: 0; }
.container > div::after {
position: absolute;
top: 50%;
left: 2rem;
transform: translateY(-50%);
color: white;
display: block;
font-family: sans-serif;
}
<div class="container">
<div class="top"></div>
<div class="middle"></div>
<div class="bottom"></div>
</div>

Related

how to layout items evenly with overlap

I want to layout list items evenly across a vertical container. All items have the same height (the last one has padding).
Normally I would use flex, but here is the challenge: The container expands with a transition to its final height - which is exactly the size of all li items stacked up with no overlap. In other words, flex is not relevant since the container height will forever be <= height of each item * the number of items.
What I need, is for the items to always spread out evenly, overlapping each other while filling up the container (starting from a complete overlap until they finally are stacked as they would with no intervention).
Here is a sandbox link to the setup of the problem:
https://codesandbox.io/s/holy-water-uln898?file=/index.html
Would appreciate your help!
const expand = () => {
document.getElementsByTagName("ul")[0].classList.add("expanded");
lis = document.getElementsByTagName("li")
for (let i = 1; i < lis.length; i++){
lis[i].style.top= i*25 + "px"
lis[i].classList.add("expand");
}
};
ul {
padding: 0;
border: 3px solid;
height: calc(25px + 8px);
transition: height 2s;
position:relative;
}
ul.expanded {
height: calc((25px * 3) + 8px);
}
li {
list-style: none;
height: 25px;
position:absolute;
left:0;
top:0;
width:100%
}
li:last-child {
padding-bottom: 8px;
}
li.item1 {
background: red;
color: darkred;
}
li.item2 {
background: green;
color: darkgreen;
}
li.item3 {
background: yellow;
color: orange;
}
button {
position: absolute;
top: 150px;
}
li.expand{
transition:top 2s;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Static Template</title>
</head>
<body>
<ul>
<li class="item1">
item1
</li>
<li class="item2">
item2
</li>
<li class="item3">
item3
</li>
</ul>
<button onClick="expand();">Click</button>
</body>
</html>
You can accomplish this with a bunch of wrappers. The list items are wrapped in an item with 0 height. Flex won't stack all the 0-height elements on top of each other unless its height is also 0 (because we must justify-content: space-between to distribute them when height is greater than 0), so the inner flex container has a height of 0 when closed, and the outer visible container (with the border) just adds a single items-worth of height to flex-container. The javascript is only for the demo.
This only works if every item has a known, static height. Transitioning height to auto is not easy by itself, let alone after you throw in some fancy overlapping.
let fullHeight = true
const button = document.querySelector(".button")
const container = document.querySelector(".container-restraint")
button.addEventListener("click", e => {
if (fullHeight) container.className = "container-restraint closed"
else container.className = "container-restraint"
fullHeight = !fullHeight
})
.list-item {
height: 100px; /* ITEM-HEIGHT */
width: 200px; /* ITEM-WIDTH */
}
.item-1 { background-color: #ff000066; }
.item-2 { background-color: #00ff0066; }
.item-3 { background-color: #0000ff66; }
.item-4 { background-color: #ffff0066; }
.container-restraint {
height: 300px; /* ITEM-HEIGHT * (N_ITEMS - 1) */
width: 200px; /* ITEM-WIDTH */
display: flex;
flex-flow: column;
transition: height 3s;
overflow: visible;
justify-content: space-between;
}
.container-restraint.closed {
height: 0;
}
.expanding-container {
width: max-content;
border: 3px solid black;
overflow: hidden;
padding-bottom: 100px; /* ITEM_HEIGHT */
}
.wrapper {
height: 0;
overflow: visible;
padding: 0;
}
<button class="button">transition</button>
<div class="expanding-container">
<div class="container-restraint">
<div class="wrapper">
<div class="list-item item-1"></div>
</div>
<div class="wrapper">
<div class="list-item item-2"></div>
</div>
<div class="wrapper">
<div class="list-item item-3"></div>
</div>
<div class="wrapper">
<div class="list-item item-4"></div>
</div>
</div>
</div>
You could use position: absolute; and jQuery animations to achieve the overlapping effect, like this:
const expand = () => {
document.getElementsByTagName("ul")[0].classList.add("expanded");
$('li').each(function(index, li){
$(li).animate({
top: (index * 25) + 'px'
}, 2000);
});
};
ul {
padding: 0;
border: 3px solid;
height: calc(25px + 8px);
transition: height 2s;
position: relative;
}
ul.expanded {
height: calc((25px * 3) + 8px);
}
li {
list-style: none;
height: 25px;
position: absolute;
top: 0;
left: 0;
right: 0;
}
li:last-child {
padding-bottom: 8px;
}
li.item1 {
background: red;
color: darkred;
}
li.item2 {
background: green;
color: darkgreen;
}
li.item3 {
background: yellow;
color: orange;
}
button {
position: absolute;
top: 150px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li class="item1">
item1
</li>
<li class="item2">
item2
</li>
<li class="item3">
item3
</li>
</ul>
<button onClick="expand();">Click</button>

Making a flexbox container height 100% in react js

I'm trying to create a flex box container of 3 columns. 3 column part works. But I want them to take complete available height excluding the app bar.
Css
.columnContainer {
display: flex;
height: 100%;
}
.leftContainer {
flex : 1;
height: 200px;
background-color: black;
}
.rightContainer {
flex : 1;
height: 200px;
background-color: blue;
}
.middleContainer {
flex : 3;
height: 200px;
background-color: green;
}
I have added 200px just to show those columns on screen. Tried 100% but it didnt show anything.
And in react js part,
<div>
<HomeBar />
<div className={'columnContainer'}>
<div className={'leftContainer'}>
</div>
<div className={'middleContainer'}>
</div>
<div className={'rightContainer'}>
</div>
</div>
</div>
Need Help :(
You can achieve this by using "vh" units, and it's a more effective way than using percentages because you don't need to set every parent height to 100% if you want the child's height to be 100%.
.columnContainer {
display: flex;
height: calc(100vh - 60px);
}
Here is an example of the 60px app bar height being excluded from the viewport height.
see patelarpan's answer for a easy way to do this
You have to set the outermost container's height to 100%. Here is your fixed code(based on your fiddle)
class TodoApp extends React.Component {
constructor(props) {
super(props)
this.state = {
items: [{
text: "Learn JavaScript",
done: false
},
{
text: "Learn React",
done: false
},
{
text: "Play around in JSFiddle",
done: true
},
{
text: "Build something awesome",
done: true
}
]
}
}
render() {
return (
<div className={'container'}>
<div className={'columnContainer'}>
<div className={'leftContainer'}>
</div>
<div className={'middleContainer'}>
</div>
<div className={'rightContainer'}>
</div>
</div>
</div>
)
}
}
ReactDOM.render( < TodoApp / > , document.querySelector("#app"))
html,
body {
height: 100%;
}
#app {
height: 100%;
}
.container {
height: 100%;
margin: 0px;
padding: 0px;
}
.columnContainer {
display: flex;
height: 100%;
}
.leftContainer {
height: 100%;
flex: 1;
margin: 10px;
background-color: black;
}
.rightContainer {
flex: 1;
margin: 10px;
background-color: black;
height: 100%;
}
.middleContainer {
flex: 2;
margin: 10px;
background-color: black;
height: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

Content box should extend to footer even if empty

I need the content box to reach to the footer even when the content box is empty. I want to achieve this using only CSS.
padding-bottom is not an option.
I don't want to use a background image, such as background-image: url center repeat-y;
How can I achieve this?
.wrap {
height: 100%;
}
.l-col {
padding-top: 0;
height: 100%;
}
.footer {
position: relative;
height: 60px;
clear: both;
float: left;
width: 100%;
z-index: 3;
}
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<div class="wrap">
<div class="container">
<div class="col-xs-12 l-col">
<div class="col-xs-12" style="padding:0px">
<table>Content</table>
</div>
</div>
</div>
</div>
Current Layout:
Desired Layout:
Using CSS's calc() function, you can use calculate the min-height of your content div.
body {
margin: 0
}
.header,
.footer {
width: 100%;
height: 60px;
background-color: grey;
}
.content {
width: 100%;
min-height: calc(100vh - 120px);
background-color: #FFF8DC;
}
<div class="wrap">
<div class="container">
<div class="header">
Header
</div>
<div class="content">
Content
</div>
<div class="footer">
Footer
</div>
</div>
</div>
If your preferred method is jQuery, the following code will work, even on page resize.
function setContentHeight() {
var headerHeight = $(".header").height();
var footerHeight = $(".footer").height();
var winHeight = $(window).height();
$(".content").css("min-height", winHeight-(headerHeight+footerHeight));
}
setContentHeight();
$(window).resize(setContentHeight);
Here you go just calculate your min height so if content gets more it will expand if you don't want that just use regular height.
body{margin:0;}
.head, .foot {
width: 100%;
background: gray;
height: 50px;
float: left;
display: inline-block;
}
.content {
width: 80%;
min-height: calc(100vh - 100px);
background: lightgray;
float: left;
display: inline-block;
}
<div class="head">Head</div>
<div class="content">hello</div>
<div class="foot">foot</div>
flex + html5, looks like a school case ...
html {
display:flex;
height:100%;
}
body {
flex:1;
display:flex;
flex-flow:column;
color:white;
}
header , footer{
text-align:center;
background:#4F81BD;
line-height:4em;
}
main {
flex:1;
display:flex;
justify-content:center;
padding-left:10%;/* cause aside is set to 10% width */
}
section {
border:30px #4F81BD solid;
padding:1em;
margin:2px;
box-shadow:0 0 0 2px , inset 0 0 0 2px ;
width:60%;/* whatever */
color: #385D8A
}
aside {
background: #4F81BD ;
box-shadow:0 0 0 2px #385D8A;
margin:auto 0;
width:10%;
min-height:30vh;/* demo purpose, use content instead */
display:flex;/* optionnal to center on XY axis */
align-items:center;
justify-content:center;
}
<header>
header (any height)
</header>
<main><!-- fill gap in between -->
<section>section, run snippet in full page mode and resize window</section>
<aside>aside</aside>
</main>
<footer>
footer (any height)
</footer>
pen to play with: http://codepen.io/gc-nomade/pen/ORyXZA

CSS Solution to Visually Align Carousel Contents and Body

I am using CarouFredSel as my carousel and I want to visually vertically align the text content within this carousel to my body content. I know you can do this with javascript (I have commented it out) by adjusting the left property of #carousel based on the browser width but I am looking for a CSS solution.
The blue screenshot on the left is displaying the website when the browser is maximized, and the 'link3' in the carousel appears to be aligned with 'content'. The red screenshot on the right is displaying the website when the browser is minimized, and 'link1' is not visually aligned with 'content'.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<link rel="stylesheet" type="text/css" media="all" href="reset.css">
<script type="text/javascript" language="javascript" src="<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>"></script>
<script type="text/javascript" language="javascript" src="http://www.sfu.ca/~jca41/stuph/jquery.carouFredSel.js"></script>
<script type="text/javascript" language="javascript">
$(function() {
$('#carousel').carouFredSel({
items: 1,
scroll: {
fx: 'crossfade',
duration: 1000
},
pagination: {
container: '#pager',
duration: 500
}
});
/*$(window).resize(function() {
var winW = $(window).width();
var carouselWidth = $('#carousel .slide').css('width');
carouselWidth = carouselWidth.replace(/[^0-9]/g, '');
if (winW > carouselWidth) {
$('#c-carousel').css('left', (winW-carouselWidth)/2 + 'px');
} else {
$('#c-carousel').css('left', '0px');
}
}).resize();*/
});
</script>
<style type="text/css" media="all">
#heroicCarousel {
height: 100%;
padding: 0;
margin: 0 auto;
min-height: 250px;
position: relative;
z-index: 1000;
text-align:center;
max-width:600px;
}
.caroufredsel_wrapper {
width: 100% !important;
height: 100% !important;
}
#carousel {
position: absolute !important;
}
#carousel .slide {
width:600px;
height:250px;
overflow: hidden;
float: left;
}
#carousel .slide .content {
font-size: 55pt;
position: relative;
top: -100px;
left: 150px;
z-index: 5;
}
#carousel .slide img {
width: auto;
height: auto;
min-width: 100%;
min-height: 100%;
}
#pager {
position: relative;
top: -700px;
left: 0;
z-index: 10;
display: block;
text-align: center;
}
#pager a {
background-color: #356;
display: inline-block;
width: 15px;
height: 15px;
margin-right: 6px;
border-radius: 10px;
box-shadow: 0 1px 1px #cef;
}
#pager a.selected {
background-color: #134;
}
#pager a span {
display: none;
}
#content {
background: yellow;
width: 300px;
height: 300px;
position: relative;
margin: 0 auto;
z-index: 20px;
top: -520px;
font-size: 60pt;
}
</style>
</head>
<body>
<div id="heroicCarousel">
<div class="caroufredsel_wrapper">
<div id="carousel">
<div class="slide">
<img src="http://www.placehold.it/600x250/ff0000/999999">
<div class="content">link1</div>
</div>
<div class="slide">
<img src="http://www.placehold.it/600x250/00ff00/999999">
<div class="content">link2</div>
</div>
<div class="slide">
<img src="http://www.placehold.it/600x250/0000ff/999999">
<div class="content">link3</div>
</div>
<div class="slide">
<img src="http://www.placehold.it/600x250/f0f0ff/999999">
<div class="content">link4</div>
</div>
</div>
</div>
<div id="pager">
<span>1</span>
<span>2</span>
<span>3</span>
<span>4</span>
</div>
</div>
<div id="content">
content
</div>
</body>
</html>
I usually do it with a wrapping elem around the divs. This elem is as wide as your widest div and any children with margin:0 auto; are centered to it. Example http://jsfiddle.net/5LJhC/1/
Very simple example but shows how as the carousel width changes the content div is centered

Html/Css - How to get an image to stretch 100% width of a container then display another image over it?

I am struggling with getting the layout of the header i have in mind together.
Here is the html so far:
<div id="header">
<img src="/img/headerBg.jpg" alt="" class="headerBg" />
<img src="/img/logo.png" alt="Logo" class="logo" />
<div id="loginBox">
other code
</div>
</div>
And the css so far:
#header {
height: 130px;
margin: 5px 5px 0 5px;
border: #0f0f12 outset 2px;
border-radius: 15px;
}
#loginBox {
float: right;
width: 23.5%;
height: 128px;
font-size: 75%;
}
.headerBg {
}
.logo {
width: 50%;
height: 120px;
float: left;
display: block;
padding: 5px;
}
What I am trying to accomplish, is have the image "headerBg.jpg" display to 100% width of the div "header", so essentially it will be the background of the div itself. Then have the image "logo.png" and the div "loginBox" display above "headerBg.jpg".
The logo should be floated to the far left end and the loginBox floated to the far right as in the css.
With the image removed, the logo and div are placed correctly, but when the image is introduced they two floated items are placed after the image in the flow.
I have tried various additions and reconfigurations but none have proven to work out how I want them to.
I have added the image in the css as a background to the header div, but it does not stretch 100% that way.
Would anyone be able to provide some insight on this?
Also any tutorials covering things like this would be a great addition to my collection!
Thank you!
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Render this</title>
<style type="text/css">
#header {
position:relative;
height: 130px;
margin: 5px 5px 0 5px;
border: #0f0f12 outset 2px;
border-radius: 15px;
}
#loginBox {
position:relative;
float: right;
width: 23.5%;
height: 128px;
font-size: 75%;
}
.headerBg {
position: absolute;
width: 100%;
height: 100%;
z-index: -1;
}
.logo {
position:relative;
width: 50%;
height: 120px;
float: left;
display: block;
padding: 5px;
}
</style>
</head>
<body>
<div id="header">
<img src="img/headerBg.jpg" alt="" class="headerBg" />
<img src="img/logo.png" alt="Logo" class="logo" />
<div id="loginBox">
other code
</div>
</div>
</body>
</html>
.header {
position: relative;
}
.headerBg {
position: absolute;
left: 0px;
right: 0px;
width: 100%;
}
Note that this will scale the image to fit the width of the <div>; if you only want it to resize horizontally then you should set the height explicitly.
You could also try max-width: 100%; if you only want the image to scale on large windows.
Just make the header background image the true background of that div. Float does not ignore other objects the way that position: absolute does.
#header {
height: 130px;
margin: 5px 5px 0 5px;
border: #0f0f12 outset 2px;
border-radius: 15px;
background: url(headerBg.jpg);
}
Set the div class which will not show any extra parts.
div {
overflow: hidden;
}
These settings worked perfect for me.. it will size ur photo for all pics..
#headerBg {
position: absolute;
top: 0px;
left: 0px;
right: 0px;
width: 100%;
height: 100%;
}
<!DOCTYPE html>
<html>
<head>
<title>W3.CSS</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta content="text/html; charset=iso-8859-2" http-equiv="Content-Type">
<!--link rel="stylesheet" href="#"-->
<style>
.mySlides {
display: none;
}
.header {
background-color: #f1f1f1;
padding: 30px;
text-align: center;
height: 195px;
display: flex;
align-items: center;
align-items: center;
justify-content: center;
}
.img2 {
float: center;
display: inline-block;
}
</style>
<style type="text/css">
.c4 {
max-width: 500px
}
.c3 {
width: 100%
}
.c2 {
display: inline-block;
text-align: center;
width: 100%;
}
.c1 {
max-width: 100%;
height: auto;
}
</style>
</head>
<body>
<h2 class="c2">Automatic Slideshow</h2>
<div id="header" class="c2">
<img class="img2 c1" src="./img/16px/avi.png" alt="Pineapple">
<h1 class="c2">
I want to be
</h1>
<div class="c4">
<img id="carousel" src="" class="c3">
</div>
</div>
<script>
//set up things
var images = [];
images[0] = "./img/16px/avi.png";
images[1] = "./img/16px/bmp.png";
images[2] = "./img/16px/cpp.png";
var n = images.length - 1;
var carouselimg = document.getElementById("carousel");
var header = document.getElementById("carousel");
// preload all images
carouselimg.style.display = "none";
for (var i = 0; i < n; i++) {
carouselimg.src = images[i];
}
carouselimg.style.display = "block";
//prepare first round
var carouselIndex = 0;
// start show
rotate();
function rotate() {
var dr = header.getBoundingClientRect();
carouselimg.style.width = dr.width;
carouselimg.src = images[carouselIndex];
//index is a global variable
//so its state will be kept and we can load the first / next image
carouselIndex++;
// increment image array index
if (carouselIndex > n) {
// do we rech the end
carouselIndex = 0
// start from begin
}
setTimeout(rotate, 2000);
// restart rotation every 2 seconds
}
</script>
</body>
</html>
try using in your css:
max-height:100%;