Issue with child height - html

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/

Related

Flexbox items not shrinking

I have 4 boxes that I would like to resize as the size of my window changes. Box 1 will shrink, however box 2, 3 and 4 do not. What am I doing wrong?
.contents {
display: flex;
justify-content: flex-end;
min-width: 0px;
}
.contents div:first-child {
flex-grow: 1;
padding: 5px;
}
.contents div {
border-left: 1px solid red;
flex-shrink: 1;
min-width: 0px;
overflow: hidden;
padding: 5px 100px;
}
<div class="contents">
<div>1 Really long text goes in here, really long text goes in here.</div>
<div>2 Lorem</div>
<div>3 Ipsum</div>
<div>4 Dolor</div>
</div>
http://codepen.io/anon/pen/OppdmQ?editors=1100#0
Thank you.
You have 100px padding on the left and right of each item (padding: 5px 100px). That's 200px of inflexible width right off the bat. Try this method instead:
.contents div {
border-left: 1px solid red;
flex: 0 1 200px; /* can't grow, can shrink, start at 200px width */
min-width: 0px;
overflow: hidden;
padding: 5px;
text-align: center;
}
revised codepen
You won't achieve the desired effect if you are going to use padding since it will take up that much of space no matter what your screen size is. So, in that case you need to change the padding using media break points or change the flex properties according to the size of the screen.

what can we do to make 1 flex item resizeable and one absolute length?

I want to make one element with a height and width of 40px and another element next to it which takes leftover space of parent element's width. so, after resize the second element will shrink and the first one will remain same.
My idea is to use flexbox properties for it, but if there isn't one I can use anything else to... :)
Try this: left one has fixed width and you can vary it according to your requirement
Here is a fiddle and below is a working code snippet
*{
box-sizing: border-box;
}
body, html{
height: 100%;
width: 100%;
margin: 0;
}
#container{
display:flex;
flex-direction:row;
}
#column-2
{
margin: 0 auto;
background-color:red;
border: 0.2em solid black;
flex-shrink:0;
flex-grow:1;
}
#column-1
{
margin: 0 auto;
width:200px;
text-align: center;
background-color: white;
border: 0.2em solid black;
flex-shrink:0;
}
<div id="container">
<div id="column-1">
content
</div>
<div id="column-2">
test content
</div>
</div>

Two DIVs 1 with static width, other fliud, but how to get right div to stack UNDER # breakpoint?

I have two divs next to each/side by side..
The LEFT div has a FLUID width.
The RIGHT div has a static wdth.
When I resize the screen/browser... it work great! (and as intended).
However because of the way it was set up:
(Fiddle example: http://jsfiddle.net/VHcPT/384/)
The RIGHT div in physically first in the mark-up..(and floated RIGHT).
However at say 768px breakpoint.. I need this RIGHT (static) DIV to stack UNDER the LEFT div.. how can I achieve this?
If I physically have the RIGHT div AFTER the LEFT div in the markup.. it would stack as expected.. but I need to have it FIRST so the fluid/static behavior in place works as it should.
So to re-cap, its NOT about getting the two divs next to each other one fluid, one static.. its how to handle that at a responsive/breakpoint.. and get the static (RIGHT) div to stack UNDER the fluid (LEFT) div
Using the fiddle example.. the RED DIV would go UNDER (stack) the GREEN lines/div.. (the green would then be full width).. at a certain breakpoint.
and because code is required now:
HTML:
<div id="contentcontainer">
<div class="rightcontainer">mm</div>
<div class="leftcontainer">
<div class="item_1">
some text
</div>
<div class="item_2">
some text
</div>
</div>
</div>
CSS:
#directorycontainer {
padding:10px 10px;
display:table;
box-sizing: border-box;
width: 100%;
font-size: 0.8em;
font-weight: normal;
}
.directory {
background: green;
margin-right: 10px;
overflow: hidden;
padding-right: 10px;
position: relative;
}
.mapcontainer {
background: red;
display:table;
width:240px;
height:480px;
float:right;
position:relative;
overflow: hidden;
}
.providercontainer{
background-color: #f7f9fb;
border: 1px solid #e1dacd;
display: table;
margin-bottom: 0.625em;
padding: 0;
width: 100%;
}
OK well looks like this works and should be an acceptable answer/solution:
Fiddle:
http://jsfiddle.net/VHcPT/389/
HTML/Markup:
<div id="contentcontainer">
<div class="leftcontainer">
<div class="item_1">
some text
</div>
<div class="item_1">
some text
</div>
</div>
<div class="rightcontainer">mm</div>
</div>
CSS:
* {box-sizing: border-box;}
#contentcontainer {
padding:10px 10px;
display:table;
box-sizing: border-box;
width: 100%;
font-size: 0.8em;
font-weight: normal;
}
.leftcontainer {
background: green;
overflow: hidden;
padding: 5px;
float:left;
width:calc(100% - 240px);
}
.rightcontainer {
background: red;
display:table;
width:240px;
height:480px;
float:left;
position:relative;
overflow: hidden;
}
.item_1{
background-color: #f7f9fb;
border: 1px solid #e1dacd;
display: table;
margin-bottom: 0.625em;
padding: 0;
width: 100%;
}
works with whatever breakpoints you set and the elements will stack correctly.
you may like my FLEXBOX alternative to you problem. It may take a bit of practice, but it will eventually give you much more control.
The FIDDLE
Below the basic CSS structure, no other 'display', 'position' or 'overflow' needed. With this structure you can mix-match any number of fixed and/or fluid columns.
.flex--box { display: flex; flex-flow: row wrap }
.flex--fluid { flex: 1 1 auto }
.flex--fixed { flex: 0 0 auto; min-width: 240px }
/* MOBILE MQ */
#media all and (max-width: 360px) {
.flex--fluid, .flex--fixed {
flex: 1 1 auto;
}
}
Let me know if you have problem with it.
And of course, do give credit if you think it is worth it.
( BTW: I changed the colors to something less retina intensive &D )

shrink middle div horizontally on browser resize

I have a 3 column layout which I'm creating using inline-block divs. The left and right columns are fixed widths but the inner column is to hold dynamic content and should expand horizontally as required by it's content width.
That's easy enough... the tricky part is that when the browser window is smaller (horizontally) than the width of the left, right and expanded middle divs, I would like the middle div to scroll and the side columns to stay fixed. In other words, the middle div's size should shrink and grow with window resize but should not grow beyond the available space.
Simply laying out the divs looks like this
https://jsfiddle.net/xzjp5xef/1/
HTML:
<div id="container">
<div id="lcol">
left
</div>
<div id="midcol">
<div id="spacer">
150px spacer
</div>
</div>
<div id="rightcol">
right
</div>
</div>
CSS:
div {
height:200px;
border-style:solid;
display: inline-block;
border-width: 1px;
vertical-align: top;
}
#container{
white-space: nowrap;
}
#lcol {
background-color:blue;
width: 100px;
}
#midcol {
background-color: yellow;
overflow-x: auto;
}
#spacer {
min-width: 150px;
margin: 10px;
height: 20px;
}
#rightcol {
background-color: red;
width:100px;
}
The point of the "spacer" div is to represent the dynamic content which in this case I've fixed to 150px plus padding. So in this case I want the divs to lay out the way they do in the above fiddle, but then when the window is shrunk horizontally, I want the middle div to scroll and the left and right divs to remain fully visible.
That fails because then the window gets a scroll bar but the middle panel remains the same width and the right hand div disappears into the scrolled region.
My next attempt was using absolute positioning
https://jsfiddle.net/n4zrLqh2/
I fixed the left div to the left and the right div to the right and set the middle div's right and left properties. This is a neat trick which allows the middle div to stretch and take up all available space. This works nicely but doesn't create the effect I'm after when the window is big - because I don't want the middle column to expand further than is necessary to contain its content.
In the end I've solved this with javascript but would much prefer a CSS solution.
Edit: To help others see what I'm trying to achieve, here's the complete javascript solution (which I'd prefer to achieve with pure CSS):
HTML:
<div id="lcol">left</div>
<div id="midcol">
<div id="spacer">150px spacer</div>
</div>
<div id="rightcol">right</div>
CSS:
div {
height:200px;
display: inline-block;
vertical-align: top;
margin: 0px;
float:left;
}
body {
white-space: nowrap;
margin:0px;
max-height: 200px;
}
#lcol {
background-color:blue;
width: 100px;
}
#midcol {
background-color: yellow;
overflow-x: auto;
}
#spacer {
min-width: 150px;
height: 20px;
background-color: gray;
margin: 5px;
}
#rightcol {
background-color: red;
width:100px;
}
JAVASCRIPT (with jquery)
function adjustSizes() {
// Sizes of middle divs are dynamic. Adjust once
// built or whenever the viewport resizes
//
var $leftDiv = $('#lcol')
var $milddleDiv = $('#midcol');
var $rightDiv = $('#rightcol');
// 1. Resize middle div to available viewport space
var maxBodyWidth = $(window).innerWidth() - ($leftDiv.outerWidth() + $rightDiv.outerWidth());
$milddleDiv.css('maxWidth', maxBodyWidth);
}
$(window).resize(function () {
adjustSizes();
});
And the fiddle: https://jsfiddle.net/bjmekkgj/2/
I think setting max-width of spacer will solve your problem in case content increases.
Set max-width to calc(100vw - 200px) if all margin and padding are 0. Otherwise adjust the value 200px taking margin, padding into account.
I have created a plunker. Please check if it solves your issue. Try checking after running plunker in spearate window
http://plnkr.co/edit/WG9v0MyiD2hiaZrOA3Yw?p=preview
For the one example you provided, since the left and right columns are positioned absolutely, you should take up the space somehow. I used padding on the middle column, then nested a "content" block inside that represents the visible part of the middle column. Then, I put overflow-x: auto; on the new content block and set a max-width on the overall container to force the new block to shrink.
(In previous edits, I was attempting to do this same thing but with floats instead of absolutely positioned divs)
* { margin: 0px; padding: 0px; }
#container {
box-sizing: border-box;
display: inline-block;
position: relative;
max-width: 100%;
border: 1px solid black;
height: 200px;
}
.column {
box-sizing: border-box;
height: 100%;
}
#left {
position: absolute;
left: 0px;
top: 0px;
bottom: 0px;
width: 100px;
border-right: 1px solid black;
background: blue;
}
#mid {
border: none;
padding: 0px 100px;
}
#mid > .content {
box-sizing: border-box;
background-color: yellow;
overflow-x: auto;
height: 100%;
}
#spacer {
width: 150px;
height: 20px;
}
#right {
position: absolute;
right: 0px;
top: 0px;
bottom: 0px;
width: 100px;
border-left: 1px solid black;
background: red;
}
<div id="container">
<div id="left" class="column">
left
</div>
<div id="mid" class="column">
<div class="content">
<div id="spacer">
150px spacer
</div>
</div>
</div>
<div id="right" class="column">
right
</div>
</div>
...and in JSFiddle form
flexbox can do that.
div {
border-style: solid;
border-width: 1px;
}
#container {
height: 200px;
display: flex;
}
#lcol {
background-color: blue;
width: 100px;
}
#midcol {
background-color: yellow;
flex: 1;
overflow-x: auto;
}
#rightcol {
background-color: red;
width: 100px;
}
<div id="container">
<div id="lcol">
left
</div>
<div id="midcol">
</div>
<div id="rightcol">
right
</div>
</div>
JSfiddle Demo (showing overflow effect).
Support is IE10 and up.
Try setting the middle div to have a max width with a percentage so it will get thinner with the screen size:
.midcol {
max-width: 25%;
}
I put a value for the max-width in there for an example, but you can change the value.

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

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%;
}