I've made a drop-down list which attaches to a text input, and the list which appears beneath has a header and footer row, and scrolling content in between. JS fiddle here:
https://jsfiddle.net/tpgjjh81/3/
It works great, except I'd like the drop-down to have a flexible height, depending on its content, up to a specified max-height. However, if I change:
DIV.dropdown {
...
height: 100px;
...
}
to:
DIV.dropdown {
...
max-height: 100px;
...
}
...then the "content" part of the list doesn't show at all when the drop-down appears, only the header and footer rows. The DIV's within have height: 100% so I would have thought these would push the outer DIV to its max-height but it doesn't appear to be working?
edit: I've also tried adding height: auto alongside the max-height but it doesn't have any effect.
See this fiddle here: https://jsfiddle.net/tpgjjh81/22/
The main issue was to do with the DIV.scroll_inner having absolute positioning with 0 edges (to fill the scroll_outer container).
Let the outer container control its own content, and limit the inner content's height to max-height: 100px.
Essentially, what you are looking for is something like this:
DIV.wrapper {
display: inline-block;
position: relative;
}
DIV.dropdown {
display: none;
position: absolute;
clear: left;
left: 0;
right: 0;
border: 1px solid black;
}
DIV.list_container {
display: table;
width: 100%;
height: 100%;
}
DIV.header,DIV.footer {
display: table-row;
background-color: lightgray;
}
DIV.scroll_outer {
display: table-row;
height: auto;
background-color: white;
}
DIV.scroll_inner {
overflow: auto;
max-height: 100px;
}
EDIT I've also removed some now unnecessary properties from the CSS, and updated this above, and in the fiddle. This should at least get you off the ground.
Best of luck in your project! :)
I cleaned up your css. Not sure why you were using display table and setting up the height etc. Just hide the parent overflow and set child overflow to scroll and that should do it.
Also I moved the border to outer container so it is not cut off.
is_visible = false;
function Toggle() {
is_visible = !is_visible;
document.getElementById("dropdown").style.display = (is_visible ? "block" : "none");
}
DIV.wrapper {
display: inline-block;
position: relative;
}
DIV.dropdown {
display: none;
position: absolute;
clear: left;
left: 0;
right: 0;
height: 100px;
border-bottom: 1px solid black;
overflow: scroll;
}
DIV.list_container {
display: block;
border: 1px solid black;
border-bottom: 0px;
}
DIV.header,DIV.footer {
display: block;
background-color: lightgray;
}
DIV.scroll_outer {
display: block;
position: relative;
background-color: white;
}
DIV.scroll_inner {
overflow: hidden;
}
<div class="wrapper">
<input type="text" size="50" value="Click me" onclick="Toggle()" />
<div class="dropdown" id="dropdown">
<div class="list_container">
<div class="header">Header</div>
<div class="scroll_outer">
<div class="scroll_inner">
Item 1<br />
Item 2<br />
Item 3<br />
Item 4<br />
Item 5<br />
Item 6<br />
Item 7
</div>
</div>
<div class="footer">Footer</div>
</div>
</div>
</div>
height: auto;
max-height: 100px;
overflow: auto;
Related
I have made an unsorted list that contains tabs that get created dynamically based on the value of my amount input field. The div of this list has its overflow set to auto to create a scrollbar when too many tabs are created. But for some reason the overflow auto doesn't work as intended.
These pictures show that I can fit a maximum of 21 tabs without a scrollbar. However, as I increase the amount of tabs they get squished together until the 24th tab and only after the 25th has been added the scrollbar appears. (The borders are for visualization purposes and show the dimensions of the div that contains the list as well as the div that contains that div)
These are the respective sections of my HTML and CSS:
#amount-and-tabs-container {
display: flex;
}
.container {
width: 50%;
display: inline-block;
}
#amount-container {
width: 10%;
min-width: 75px;
}
#tabs-container {
width: 100%;
overflow: auto;
border: 1px solid blue;
}
#tabs {
display: flex;
list-style-type: none;
margin: 0;
padding: 0;
border: 1px solid red;
}
.tab {
cursor: pointer;
text-align: center;
font-weight: bold;
padding: 10px;
margin-left: 20px;
width: 24px;
min-width 24px;
background-image: url("tab.png");
background-size: 100% 100%;
}
.tab.active {
background-image: url("tab_active.png");
}
.tab:hover {
background-image: url("tab_hover.png");
}
<div id="amount-and-tabs-container">
<div class="container" id="amount-container">
<label id="amount-label" for="amount">Amount:</label>
<input type="number" id="amount" value="1" min="1">
</div>
<div class="container" id="tabs-container">
<ul class="tabs" id="tabs"></ul>
</div>
</div>
I have tried to add a width and min-width to the tabs, but it doesn't do anything in regards to this problem. I suspect the cause to be the margin on the tabs, but I am not sure. My leading theory is that the margin gets prioritized above the width.
Answer:
'flex-shrink: 0' fixed this.
For reporting purposes I want a div report-canvas with a fixed height in mm:
.report-canvas {
height: 335mm;
min-height: 335mm;
max-height: 335mm;
}
A page has this structure:
<div class="a4">
<div class="header"></div>
<div class="report-canvas"></div>
<div class="footer"></div>
</div>
This works fine when .report-canvas doesn't have any child elements. But when I start to add h2's, table's and other div's, then the footer is pushed down outside of the page and the report-canvas is too big. How can I force report-canvas to always have the same size regardless of child elements?
This is the CSS of the other elements:
.a4 {
page-break-before:always;
clear: both;
margin: 0 auto;
border: 1px solid #888888;
width: 250mm;
height: 365mm;
}
.header {
padding-bottom: 10px;
height: 35px;
}
.footer {
padding-top: 10px;
height: 25px;
}
You can either use overflow: hidden or overflow: scroll on report-canvas
I need to have a div with one line of images, the amount of images inside the div can be changed at any time. So I want I horizontal scrollbar.
I have a structure like the following. I tried to achieve it with css, but unfortanetly it doesn't work.
<div id="scroll-wrapper">
<div id="thumbnails">
<div class="thumbnail-container active">
<img src="foobar" />
</div>
<div class="thumbnail-container">
<img src="bar" />
</div>
</div>
</div>
Code with CSS:
http://jsfiddle.net/c622c3w9/2/
Note that I do not want a solution with javascript.
I had to remove the float: left to get scroll to work
#thumbnails {
padding-bottom: 10px;
max-height: 50px;
min-width: 100px;
overflow-y: hidden;
overflow-x: scroll; /*add this so you get bottom scrollbar*/
white-space: nowrap; /*add this to stop images wrapping so thay stay on one line*/
}
.thumbnail-container {
display: inline-block;
position: relative;
line-height: 5px;
border: 2px solid steelblue;
margin: 3px;
display: inline-block;
/*float: left; remove this otherwise scroll will not work*/
margin-bottom: 15px !important;
}
http://jsfiddle.net/c622c3w9/3/
You only need to do two things. Fiddle.
.thumbnail-container {
.......
// float: left; <== Remove
}
#thumbnails {
.....
white-space: nowrap; // Add
}
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.
I'm trying to hide and show a table row using css-tables and pure JavaScript (No jQuery).
I've got a div with the display set to table-row and a nav inside of it. No matter what I do, border-collapse etc, the div still maintains some of it's height.
Any ideas?
HTML:
<!-- Header -->
<header id='header'> <!-- Table Row 1 -->
<div id="header-table">
<div id='back'>
<button id='back-button'>←</button>
</div>
<div id="title">
<h1 id='title-h1'>Title</h1>
</div>
<div id="menu">
<button id='menu-button'>≡</button>
</div>
</div>
</header>
<nav id="menu-nav">
Introductory Page
Activity List
Settings
About
</nav>
<div id="body"> <!-- Table Row 3 -->
<div id="wrapper">
CSS
header#header {
position: relative;
display: table-row;
}
div#menu-nav-cell {
position: relative;
display: table-row;
text-align: center;
overflow: hidden;
background: yellow;
}
nav#menu-nav {
display: table-row;
height: 0em;
width: 100%;
color: #000;
background: pink;
}
div#body {
position: relative;
display: table-row;
height: 100%;
}
div#wrapper {
position: relative;
height: 100%;
}
Why not simply using display: none?
Maybe I misunderstood, since you said you have a div with a nav inside, but I cannot see that in your html sample.
I think you want to show/hide the navigation. This can be done by adding this css rule:
nav#menu-nav.hidden {
display: none;
}
and javascript
document.getElementById("toggle").onclick = function () {
document.getElementById("menu-nav").classList.toggle("hidden");
}
jsFiddle
If you want to animate the height, you can do this:
/* new rules that I added */
nav#menu-nav {
line-height: 1em;
-webkit-transition: line-height .2s, background-color .2s;
}
nav#menu-nav a {
display: inline-block;
overflow: hidden;
height: 1em;
-webkit-transition: height .2s;
}
nav#menu-nav.hidden {
line-height: 0em;
background-color: transparent;
}
nav#menu-nav.hidden a {
height: 0;
}
The trick is to use overflow: hidden; display:inline-block for the table cells, instead of display:table-cell.
This way, changing the height and line-height to zero works fine.
However there is still some height (around 3px) still visible, so I decided to animate the background-color to transparent as well. If you comment that part that animates the background color, you will understand what I mean.
jsFiddle v2