Child is larger than parent with max-height. Overflow has no effect - html

I want to have a parent element which has a maximum height and a child element which fills this parent element. If the contents of the child are exceeding the parent a scrollbar should appear. I tried to solve it like this:
div.parent {
max-height: 50px;
width: 100px;
border: 1px solid black;
}
div.child {
height: 100%;
overflow-y: auto;
}
<div class="parent">
<div class="child">
<div class="some-content">
abcde<br>abcde<br>abcde<br>abcde<br>abcde<br> abcde
<br>abcde<br>abcde<br>abcde<br>abcde<br> abcde
<br>abcde<br>abcde<br>abcde<br>abcde<br> abcde
<br>abcde<br>abcde<br>abcde<br>abcde<br> abcde
<br>abcde<br>abcde<br>abcde<br>abcde<br>
</div>
</div>
</div>
Unfortunately this does not work as expected. The child grows over the parent.
Please respect, that setting overflow-y: auto to the PARENT is NOT an option, as it is suspected to hold other items that should not be scrolled. The child is suspected to fill the space that is left in the parent. See live DEMO for more information.
Live DEMO

As far as i'm aware there is no easy way to do this with CSS. Essentially you're asking the browser to fill the remaining space with the scrollable element. You can do this with JavaScript (this example uses jQuery because I'm lazy):
$('.parent').each(function(){
$(this).children('.child').height($(this).height() - $(this).children('.sibling').height()+"px");
});
http://jsfiddle.net/BUxUe/13/

You can try to use Flexbox.
div.parent {
max-height: 300px;
width: 200px;
border: 1px solid black;
display: flex;
flex-direction: column;
}
div.sibling {
border: 1px solid red;
flex: 0 0 auto;
}
div.child {
overflow-y: auto;
border: 1px solid blue;
flex: 0 1 auto;
}
I'm not sure, if this is a kind of hack. But it seems to solve this problem.

Check this out Fiddle
div.parent {
max-height: 50px;
width: 100px;
border: 1px solid black;
overflow:scroll;
}
div.child {
height: 100%;
}

Related

Remove single pixel gap between child and parent div

Here is a simple block of code:
<style type="text/css">
.parent {
position: relative;
width: 75vw;
height: 300px;
border: 5px solid #000;
}
.child {
width: 100%;
height: 100px;
background-color: #999;
}
</style>
<center>
<div class="parent">
<div class="child"></div>
</div>
</center>
But, the results are different when viewed in different screen widths.
Here, the child div completely fits the parent div at a certain screen width.
But here, when at a different screen width, a white space of about 1px appears on both the sides of the child div.
How can I get rid of this white space and make sure that the child div completely fits the parent div?
The issue lies with the border you've used and the way browsers handle this. Setting the box-sizing to border-box solves this issue. It's a common one but once you know it you'll be able to better spot it.
.parent {
position: relative;
width: 75vw;
height: 300px;
border: 5px solid #000;
margin-left: auto;
margin-right: auto;
box-sizing: border-box;
}
.child {
width: 100%;
height: 100px;
background-color: #999;
margin: 0;
}
<!DOCTYPE html>
<div class="parent">
<div class="child"></div>
</div>
Also, you don't need to define text/css in your tags these days, browsers know what the code is. Also try not to use it inline unless it was just for this question. Similarly, the <center> tag has been depreciated which means it's no longer supported in HTML 5 so you should center things using margin or flex. Margin is the easiest so that's why I've added that here.
Sometimes browsers will treat things differently in quirks mode too, so make sure you have a doctype declaration.
This is because you are using Chrome browser.
I have the same behavior with the very simple code:
<div class="container">
<div class="item-a">item A</div>
</div>
* {
box-sizing: border-box;
}
html,
body {
height: 100%;
}
.container {
width: 500px;
height: 500px;
border: 5px solid black;
background-color: cornflowerblue;
}
.item-a {
width: 300px;
height: 140px;
background-color: orange;
border: 3px solid crimson;
}
At 100% zoom it has a gap. When I zoom, the gap disappears, but when I zoom again - the gap between container and item-a may or may not show up again (you can notice cornflower background of 1px between a parent and child borders).
This is how Google Chrome handles things in both Linux and Windows 11 at the moment.
Then I gave a shot to view the same code via Firefox and there is no gap regardless of zooming.
Contrary to the many answers suggesting to set box-sizing: border-box, I used content-box instead and it fixed my issue: box-sizing: content-box
Try set child with the same width: 75vw;
.parent {
position: relative;
width: 75vw;
height: 300px;
border: 5px solid #000;
}
.child {
width: 75vw;
height: 100px;
background-color: #999;
}
<center>
<div class="parent">
<div class="child"></div>
</div>
</center>

Positioning divs inside a container

I have a general, possibly beginner question about HTML.
#container {
height: 200px;
max-width: 600px;
border: 1px solid black;
margin: auto;
margin-top: 10px;
}
#item1 {
height: 100px;
max-width: 200px;
border: 1px solid red;
}
#item2 {
height: 100px;
max-width: 200px;
border: 1px solid blue;
}
<div id="container">
<div id="item1"></div>
<div id="item2"></div>
</div>
My question is, why do #item1 and #item2 divs go underneath each other as opposed to next to each other? Isn't it true that they are no longer block-level elements because I have specified a set width for them? Why are they not lined up next to each other inside of #container? The #container has more than enough width to accommodate both items.
Note: This is strictly for learning/curiosity. I know that I can use margins and positioning to place them where I want to. However, I'm just curious as to why it behaves this way.
Thanks.
Div elements are block elements, unless you specify the display property to inline or inline-block it wont align to to the right like other inline elements do.
adding display : inline-block to the css of div's will give you what you want.
You have two ways to place you blocks horizontally: display property or float property.
It doesn't matter that you have set width to your elements. They are still block and displayed vertically.
To change this behaviour, use stylesheet (note that in both cases width, not max-width should be set):
#container {
height: 200px;
max-width: 600px;
border: 1px solid black;
margin: auto;
margin-top: 10px;
}
#item1 {
height: 100px;
width: 200px;
border: 1px solid red;
display: inline-block;
}
#item2 {
height: 100px;
width: 200px;
border: 1px solid blue;
display: inline-block;
}
or this:
#container {
height: 200px;
max-width: 600px;
border: 1px solid black;
margin: auto;
margin-top: 10px;
}
#item1 {
height: 100px;
width: 200px;
border: 1px solid red;
float: left;
}
#item2 {
height: 100px;
width: 200px;
border: 1px solid blue;
float: left;
}
<div> tag always start with new line if you are not using frameworks like bootstrap or other. If you want to see multiple items in single line then add css like display: inline-block
just add float:left; property in child divs or display:inline-block; https://jsfiddle.net/8tvn0kw6/5/
div is the standard block-level element. A block-level element starts on a new line and stretches out to the left and right as far as it can. Other common block-level elements are p and form, and new in HTML5 are header, footer, section, and more.
Even if you specify width it wont allow other elements right next to it. This the property of block level element.
Use the css inline-block it will occupy the specified width or content width.
https://developer.mozilla.org/en-US/docs/CSS/display
The height of the container should be the sum of heights of the child divs and the heights of the borders of the children
ie., height of parent container = 100+ 100+ 1+ 1+ 1+ 1 = 204px
#container {
height: 204px;
}
The #container ie you div has a display property of block. This is a default property if you don't set it to anything else. In your case the div takes this default display property.
To view #item1 and #item2 side by side just use display: inline-block in your #container.
Please replace your class like below.
#item1{
height:100px;
max-width:200px;
border:1px solid red;
display:inline-block;
}
#item2{
height:100px;
max-width:200px;
border:1px solid blue;
display:inline-block;
}

Issue with child height

Okay, so i have my parent DIV (black), and 3 children.
CSS rules:
#parent{
height:130px;
}
#description{
max-height: 80px;
}
And that's actually pretty much it for now.
What I am trying to do
#title should resize according to text inside. It can be from one, to 5-6 lines of text (it's a span, can be div - any difference?)
#city is like 99% of the time one line text (one word actually). Might happen text gets too long, and needs to be wrapped to two lines.
#description is a div, which CANNOT go outside the parent box. I need it to have dynamic height - as for later, i use some plugin to cut the text according to height of it and add "..." in the end.
Image shows what it looks like now, when i put too much text in title, and i would like, description to be max 80px, but CAN be less, if #title takes more place.
JsFiddle
EDIT: Changed image
You may want to try flexbox for such a layout. It may not provide you with a pixel perfect layout on the kind of complex rules you have, but it will still be a powerful way to control.
Fiddle: https://jsfiddle.net/abhitalks/kwq2L3y7/6/
Snippet:
#parent {
border: 1px solid black;
height: 200px; width: 80px;
float: left; margin: 16px;
display: flex; flex-direction: column;
}
#title {
flex: 2 1 auto; /* can grow twice, can shrink, auto height */
border: 1px solid red;
overflow: auto;
}
#city {
flex: 1 1 20px; /* can grow, can shrink, accommodate in 20px */
border: 1px solid green;
overflow: hidden;
}
#description {
flex: 0 1 80px; /* cannot grow, can shrink, accommodate in 80px */
border: 1px solid blue;
overflow: hidden;
}
<div id="parent">
<div id='title'>Title</div>
<div id="city">City</div>
<div id="description">Description</div>
</div>
<div id="parent">
<div id='title'>Long Title can be of several lines and can grow many lines</div>
<div id="city">City can be in 2 lines</div>
<div id="description">Description which is very long and it will not grow beyond 80px</div>
</div>
<div id="parent">
<div id='title'>Title</div>
<div id="city">City can be in 2 lines what if it is larger</div>
<div id="description">Description will remain at 80px</div>
</div>
What you want to get, you need to set height: 100% in #description.
Use like this:
#parent{
border: 2px solid black;
overflow: hidden;
}
#description{
border: 2px solid blue;
height: 100%;
}
demo
You may display the text in ellipsis.
I don't get what you exactly want to do, but you should have a look on the 'overflow' method with for example:
#parent{
overflow-y: hidden;
}
or
#parent{
overflow-y: scroll;
}
If you want the height to be dynamic, you could try use min-height
#parent {
min-height:130px;
width: 80px;
}
#description {
min-height: 80px;
}
https://jsfiddle.net/arty_/x8f7v25h/

How to make child div scrollable when it exceeds parent height?

I have 2 child divs nested in a parent div in row-column pattern: the parent is a column, and the children are rows.
The upper child div is of variable height, but is guaranteed to be less than the height of the parent div.
The lower child div is also of variable height. In some cases, the heights of the child divs will make the lower child div exceed the parent. In this case, I need to make the lower div scrollable. Note that I want only the lower div to be scrollable, not the whole parent div.
How do I handle this?
See attached jsfiddle for case example: http://jsfiddle.net/0yxnaywu/5/
HTML:
<div class="parent">
<div class="child1">
hello world filler
</div>
<div class="child2">
this div should overflow and scroll down
</div>
</div>
CSS:
.parent {
width: 50px;
height: 100px;
border: 1px solid black;
}
.child1 {
background-color: red;
}
.child2 {
background-color: blue;
}
Because this post is still ranking very high in Google, I'd like to post a better solution using flexbox. Actually this is very simple.
Use display: flex, flex-direction: column and overflow: hidden for parent and overflow-y: auto for child.
.wrapper {
display: flex;
flex-direction: column;
overflow: hidden;
}
.scrollable-child {
overflow-y: auto;
}
Here's the pen:
https://codepen.io/pawelsas/pen/vdwjpj
Overflow only works when you give it a value to overflow when greater than. Your value is relative to how big the top is, so using jQuery, grab that value then subtract from the parent.
$(document).ready(function() {
$(".child2").css("max-height", ($(".parent").height()-$(".child1").height()));
});
and add overflow's to the children
.child1 {
background-color: red;
overflow: hidden;
}
.child2 {
background-color: blue;
overflow: auto;
}
http://jsfiddle.net/m9goxrbk/
Use overflow property:
.parent {
width: 50px;
height: 100px;
border: 1px solid black;
overflow: auto;
}
jsFiddle
EDIT:
if you want only second div to be scrollable, you need to change it height to 30px so child1 and child2 will exactly fit the parent height and add overflow property there:
.parent {
width: 50px;
height: 100px;
border: 1px solid black;
}
.child1 {
height: 70px;
background-color: red;
}
.child2 {
height: 30px;
background-color: blue;
overflow: auto;
}
jsFiddle

How to deal with child's overflowing border out of it's parent container?

I'm trying to figure out what are ways to stop borders from overflowing from it's parent container.
The only solution that I can come up is to set childs width and height by using calc() to calculate and subtract width and height of child's border.
Is there any better ways with dealing with this?
What solution would be suitable for pre-IE8?
Here's jsFiddle example.
CSS
.container {
width: 100px;
height: 100px;
margin: 0;
padding: 0;
clear: both;
background-color: purple;
}
.child {
width: 100%;
height: 100%;
border: 5px solid red;
}
HTML
<div class="container">
<div class="child">
text
</div>
</div>
you have set the width and height of child element to 100 percent so obviously it will be equal to the container one. Now setting a border,it will take extra width and height that will overflow.
so the first solution is the changing dimensions.
.child {
width: 90%;
height: 90%;
border: 5px solid red;
}
Note-90% is only in this case.
and the other solution is
.child {
width: 100%;
height: 100%;
border: 5px solid red;
box-sizing:border-box;}
As #dlev said:
One option is to set box-sizing: border-box; on the child, which forces the border to be considered part of the child element's "box", rather than just the content.
But even if you one to use calc css method then just deduct the border size:
.child {
width: calc(100% - 5px);
height: calc(100% - 5px);
border: 5px solid red;
}
demo