Search code examples
cssoverflowviewport-units

How do you get a div to hide/scroll overflow and scale to the viewport with consistent margins?


(EDIT: my current code added to bottom of post)

I need to set a value for the height of the div in order for it to hide/scroll overflow properly, but I don't want a div at a specific pixel height. I can solve that by using % or vh units, but I don't actually want to use those units. By that, I mean I don't want my div to always be, for example, 2/3 of the page, because that means the bottom of the div will be a different distance from the bottom of the browser window, like this-

* {
  padding: 0;
  margin: 0;
}

html, body {
  width: 100%;
  height: 100%;
}

body > div {
  width: 90%;
  height: 90%;
  background: yellow;
}
<!DOCTYPE html>

<html>
<head>

  <link rel="stylesheet" href="style2.css">

</head>

<body>

  <div>
  </div>

</body>
</html>

-I want it to be a consistent distance from the bottom of the browser window, like this-

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


div {
	background-color: yellow;
	width: 350px;
  position: fixed;
  left: 10px;
  top: 10px;
  right: 10px;
  bottom: 10px;
}
<!DOCTYPE html>

<html>
<head>

  <link rel="stylesheet" href="style2.css">

</head>

<body>


	<div>
	</div>


</body>
</html>

(for visual representation primarily, I am not really using the code itself as an example)

Basically, I want my div to be a variable height and hide/scroll overflow, but always 10px from the bottom.

I think these describe the same problem I'm having:

Setting a length (height or width) for one element minus the variable length of another, i.e. calc(x - y), where y is unknown

Getting a scrollable child div to Vertically fill the remainder of its parent dynamically

The answers there are to use tables or flexbox - are these the only options (without using javascript)?

My code:

* {
	margin: 0;
	padding: 0;
}

body {
	font-family: Helvetica, Arial, sans-serif;
	overflow-x: hidden;
	overflow-y: hidden;
    width: 100%;
    height: 100%;
}

p {
	font-size: 9pt;
}

a {
	text-decoration: none;
	color: black;
}


.container { /*this contains all the divs!!*/
	padding: 10px;

}

.header {

}

.name {
	float: left;
	width: 25vw;
	padding-right: 5vw;
}

.about {
	width: 65vw;
}



.main { /*this contains divs 'left' and 'right'*/
	/*background-color: #CCCCCC;*/
	clear: left;
	padding-top: 10px;
	width: 95vw;

}

.left {
	/*background-color: #E6E6E6;*/

	float: left;
	min-height: 10px;
	width: 25vw;
	padding-right: 5vw;
}

.hold { /*this is how i tried your solution*/
	position: relative;
	height: calc(95vh - 10px);
}

.right { /*this is my problem div*/
	background-color: #FFFF00;

	width: 65vw;
	height: 100%;
 	overflow-y: hidden;
 	overflow-x: hidden;
}

.lorem {
	margin-right: 20vw;
}
<!DOCTYPE html>

<html lang="en">
<head>
  <meta charset="utf-8">

  <title> Name </title>

  <link rel="stylesheet" href="style.css">

</head>

<body>

<div class="container">

	<div class="header">

		<div class="name">
			<a href="index.html"> <p> Name </p> </a>
		</div> <!-- end div name -->

		<div class="about">
			<a href="index.html"> <p> about </p> </a>
		</div> <!-- end div name -->

	</div> <!-- end div header -->


	<div class="main">

		<div class="left">

		</div> <!-- end div left -->

		<div class="hold">
		<div class="right">
		
		<div class="lorem">
		<p> 
			Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam feugiat facilisis purus at fermentum. Etiam ultricies iaculis nulla maximus cursus. Maecenas justo nulla, suscipit a dapibus at, lobortis nec mauris. Mauris egestas mi sit amet risus convallis, in hendrerit lorem maximus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse sollicitudin tempor libero, nec molestie dui tempor sit amet. Aenean molestie ex id nisl venenatis, quis tincidunt lectus porta. Vivamus aliquam lobortis nulla, id porta leo consequat sollicitudin. Ut iaculis neque placerat ipsum placerat tincidunt.

			Quisque libero sem, hendrerit quis urna sit amet, mollis venenatis nisl. Morbi vel neque rhoncus, congue purus ac, condimentum nunc. Morbi vestibulum metus nec velit eleifend, ac sodales nulla posuere. Praesent id fermentum massa. Morbi vestibulum lorem nulla, ac vestibulum nunc auctor non. Donec ultricies placerat mauris, at pretium nibh finibus eu. Suspendisse gravida neque nisl, sit amet bibendum ante placerat eget. Sed laoreet suscipit turpis vitae ullamcorper. Mauris quis pharetra eros. Curabitur quis diam non dui elementum facilisis vel ac sem. Duis vitae augue vitae mi pulvinar placerat ut quis purus. Donec sagittis maximus aliquam. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.

			Phasellus pharetra nisi arcu, in laoreet lacus convallis sed. Nam euismod ligula felis, ut laoreet nisl sodales eget. Maecenas cursus, augue vitae suscipit laoreet, purus magna bibendum tellus, sed maximus ex dui ac velit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nulla eget aliquet tellus, in viverra sapien. Sed eget urna mauris. Morbi dapibus dolor et felis viverra condimentum sed a nisl. Integer congue cursus ultrices. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Suspendisse nulla risus, pulvinar eget odio vitae, scelerisque cursus magna. Nam maximus eros vitae massa euismod, vel tempus felis vulputate.

			Nunc blandit massa a nisl viverra, vitae molestie ex rhoncus. Pellentesque finibus luctus nisi. Sed quis luctus metus. Nullam sed augue ultrices, lacinia dolor ac, egestas ante. In non nisi nibh. Sed vitae dui libero. Duis ut ullamcorper urna. Phasellus quis fringilla leo.

			Nulla porta tellus ut nibh pharetra dapibus. Mauris ullamcorper egestas aliquam. Cras posuere scelerisque imperdiet. In ultrices, leo eu molestie bibendum, augue dui semper ante, vel faucibus nibh enim sed eros. Mauris ipsum dui, placerat et tincidunt vitae, laoreet vel enim. Praesent at ligula et neque placerat blandit sed vulputate ipsum. Phasellus sodales, odio nec aliquam pretium, augue lacus mattis quam, nec vulputate purus lorem vitae nisi.

			Suspendisse nisl ipsum, volutpat ac dapibus at, tincidunt eget nulla. Mauris ornare a nisi ac fringilla. Maecenas leo sapien, vulputate in dictum a, feugiat in eros. Aliquam sit amet sagittis leo. Mauris metus nisl, convallis eget mollis ut, ullamcorper eu tellus. Pellentesque eu dolor tempor, bibendum leo vitae, maximus velit. Aenean volutpat neque sit amet tellus mattis euismod.

			Quisque nec vehicula orci. Curabitur varius fringilla risus, convallis tincidunt velit porttitor vitae. Aenean in lacus nec nunc tempor dignissim nec pretium sem. Nullam finibus odio quis metus ornare, in fermentum elit rutrum. Proin vitae dui in metus vehicula sodales. Donec massa neque, suscipit ac est quis, ultrices auctor risus. Cras eu auctor lectus. Nam sagittis vulputate hendrerit. Maecenas consequat odio justo, at malesuada nulla ullamcorper a. Donec arcu tellus, dignissim ut velit vel, consequat scelerisque dolor. Curabitur dictum vel risus quis consequat.

			Pellentesque fringilla eu nisi sed tincidunt. Nulla feugiat sit amet purus sit amet cursus. Suspendisse nibh purus, tincidunt eu congue ut, ultricies id lectus. Phasellus convallis in nibh vel molestie. Nunc condimentum congue justo. In congue, turpis at vulputate imperdiet, dolor erat ultricies turpis, vitae egestas est augue in nisl. Ut ut leo diam. Duis vulputate ligula velit, vitae volutpat felis viverra a. Maecenas justo quam, lobortis a placerat ut, ullamcorper ac lorem. Sed eu vehicula odio.

			Fusce id mauris ornare, mollis mi at, vulputate turpis. Praesent a risus feugiat, rutrum lacus nec, sodales nisi. Nulla ullamcorper libero pretium lacus accumsan, eu tempor mi porta. In tincidunt porta feugiat. Cras lectus arcu, convallis nec neque ac, vestibulum pretium ex. Curabitur mi ipsum, commodo ut eros eget, fringilla fringilla tortor. Curabitur maximus tellus ut turpis malesuada, auctor semper lectus porta. Suspendisse non sapien sagittis, dapibus tellus et, egestas quam. Aliquam vitae massa sit amet urna rhoncus rutrum sit amet et lorem. Phasellus gravida justo ut vulputate vestibulum.

			Nunc sed tempus metus, sit amet volutpat mi. Quisque sed metus rutrum, iaculis enim sed, sodales lacus. Quisque quis mi ac sapien scelerisque efficitur lacinia et nunc. Proin tincidunt scelerisque turpis, non euismod ante interdum at. Sed vitae velit scelerisque, placerat nulla in, egestas justo. Mauris urna orci, pulvinar a nibh a, luctus pellentesque mauris. Nulla faucibus hendrerit urna non venenatis. Quisque nulla mi, suscipit sit amet nunc eu, dictum ullamcorper tellus. Donec lacus libero, commodo quis mauris pellentesque, feugiat iaculis nisl. Nulla facilisi. Suspendisse sed risus quis risus fringilla condimentum. Aenean aliquet in eros vel volutpat. Vivamus malesuada ultrices lorem sit amet feugiat. In interdum leo ac orci sollicitudin, maximus vestibulum nisl gravida. Sed venenatis pharetra fringilla. Etiam mauris risus, cursus et est tristique, mattis venenatis nisi.

		</p>
		</div> <!-- end div LOREM -->

	</div> <!-- end div main -->
	</div> <!-- end div hold -->
  
</div> <!-- end div container -->

</body>
</html>


Solution

  • You're on the right track! You can combine vh with calc to get the desired effect.

    height: calc(100vh - 10px) - assuming the element is positioned at the top of the screen, that'll achieve the effect you're describing.

    To handle scroll/overflow, you'll need an inner container - a div inside the one you set the height property on. Give that inner div { height: 100%; overflow: auto; } and you should be all set.

    Here's a demo - to see it working, use the full screen view and shrink your browser's height.

    /* These styles are just to make this easier to see,
    and to normalize the display a little. */
    * { box-sizing: border-box; margin: 0; padding: 0; }
    .page { width: 100px; border: 2px solid; }
    
    
    /* Here's the box that locks to some distance from the bottom, in this case 30px */
    .outer {
    height: calc(100vh - 30px);
    position: relative;
    border: 1px solid blue;
    }
    
    /* And here's the scrollable container inside it */
    .inner {
    height: 100%;
    overflow: auto;
    }
    <div class="page">
      <div class="outer">
        <div class="inner">
        content content content content
        content content content content
        content content content content
       </div>
     </div>
    </div>