display: table row does not allow scroll - html

I am currently designing a book website and on the right-hand side want to have a "Table of contents" which is in a fixed position and scrollable. I set the header for my website to "display: table-row" and similarly did so with the table of contents and its internal elements. (A header and a the scrollable list of chapters) As I understand it, display: table row should make a div element fill the remaining height and only the remaining height. [1] However, in this case, the content continues offscreen instead of allowing the user to scroll through it. (You can see the problem on this jsfiddle: https://jsfiddle.net/chrmon2/9wzjckvn/6/)
My css:
#container {
height: 300px;
border: 1px solid black;
}
#header {
background: blue;
display: table-row;
}
#toc h1 {
background: red;
display: table-row;
}
#toc #content {
background: yellow;
overflow-y: scroll;
display: table-row;
}
Is this not a capability of display: table-row or am I doing something wrong? Thanks
https://www.whitebyte.info/programming/css/how-to-make-a-div-take-the-remaining-height

As I understand it, the effect you want is as follows:
When there is remaining space, stretch the table of contents items;
When the space is too small, begin scrolling.
This is an ideal application of CSS Flexboxes. Flexboxes allow you to define how items stretch (or don't), how they align with each other, how they wrap etc.
In this case, we're going to use flexboxes for all the divs in this example.
.container, .toc, .content {
display: flex; /* begins flexbox layout */
flex-direction: column; /* Flexboxes can be aligned from left-to-right
or from top-to-bottom. In this case, we want
them to be top-to-bottom. */
flex-grow: 1; /* On .container, this does nothing. However, for
children of Flexboxes, this tells them to grow
if any space is still available. */
min-height: 0; /* For a more complicated reason, this is necessary
to make flexboxes scroll correctly. This needs
to be set on all the flexboxes in this example. */
}
.toc .content .item {
flex-grow: 1; /* Make items grow when there is room available */
}
.content {
overflow-y: scroll;
}
You can see the effects of this at this JSFiddle.

Just remove display: table-row from #toc #content and add this :
#content{
max-height:200px;
}
height can be as per your requirement.

Related

How do I align inline element to the side of a centered div with 50vw so that it resizes properly?

I have a div that is set to be 50% of the page's width at all times, and is centered.
I would like to add an element to it's side so that the element touches the div's left edge (on different screen sizes). The element has a fixed max-width.
I've tried:
#element {
position: absolute;
align: left;
padding-left: 3vw;
}
It works on most common screen sizes, but as I go very small or very big the element either overlaps with the div or there is a gap. What I would like ideally would be for the element to stick to the side of the div.
Absolute positioning is very problematic for this kind of layout. I recommend a flexbox layout.
In order to achieve this layout we will need to add a couple divs. One div to act as the 3rd column, I gave it the class ghost because it will contain nothing although the demo here uses a red border so you can see it.
The other div I added wraps the special element you want to stick to the middle div. This is so the element wrapper (.element-wrap) is a flex child, not the element itself.
Next, give the container of these 3 divs display: flex, turning it into a flexbox container:
section {
display: flex;
align-items: center; /* vertical alignment */
justify-content: center; /* horizontal alignment */
}
The align-items property allows you to vertically align the items inside, while justify-content allows you to align them horizontally.
The center div, which I gave a blue background, will of course be in the middle of the layout and maintains its width with width: 50vw;. The 2 divs on the side have a class applied .flex-child which get this CSS:
.flex-child {
flex-grow: 1;
flex-basis: calc((100% - 50vw) / 2);
}
flex-grow: 1 allows those side divs to expand with the size of the screen. The flex-basis rule determines the starting size, where I am using a calc() function to dynamically calculate the width.
Now, the special element with the yellow background needs to be positioned next to the blue background, which is achieved here by turning its wrapper div into a flexbox too and aligning the content to the right:
.element-wrap {
display: flex;
justify-content: flex-end;
}
* { box-sizing: border-box; }
section {
display: flex;
align-items: center;
justify-content: center;
/* just for demo */
background: #eee;
}
.flex-child {
flex-grow: 1;
flex-basis: calc((100% - 50vw) / 2);
/* just for demo */
border: 1px solid red;
}
.half-screen {
width: 50vw;
min-height: 300px;
background: dodgerblue;
}
.element-wrap {
display: flex;
justify-content: flex-end;
}
.element {
/* just for demo */
background: yellow;
}
<section>
<div class="flex-child element-wrap">
<div class="element">
ELEMENT that we are<br>
getting to stick to the side<br>
of the 50vw div.
</div>
</div>
<div class="half-screen">
50vw DIV
</div>
<div class="flex-child ghost"><!-- nothing here --></div>
</section>

Using flexbox, vertically center items and respect top 150px space of flexbox container

I am trying to craft a flexbox in CSS with the following characteristics:
Three items stacked and centered within the middle of the flexbox
One item locked to bottom of the flexbox
Flexbox is set to a size of 100vh and 100vw, taking up visible screen area
Items within flexbox must not occupy the top 150px of the flexbox. This may push some items below the viewable area (see "Desired Result 3" in image below)
Ideally, a pure CSS solution is feasible with the HTML elements provided
The Problem
The vertically centered boxes won't honor the 150px space I would like to put at the top of the flexbox, and I haven't been able to create an elegant way to make sure the items don't float up past the top of the screen if I make the window too short. That is, the example in "Desired Result 3" in the image above remains elusive.
Example Code
HTML:
body {margin:0; font-family: sans-serif; font-weight:bold;}
.parentFlexBox {
background-color:grey;
display: flex;
flex-direction: column;
margin-top:0;
align-items: center;
justify-content: center;
flex-wrap: nowrap;
height:100vh;
width:100vw;
}
.itemA, .itemB, .itemC, .itemD { padding:5px; text-align:center; margin-bottom:5px; color:#fff;}
.itemA { background-color:red; width:50px; margin-top:auto;}
.itemB { background-color:hotpink; width:150px; height:50px}
.itemC { background-color:purple; width:40px; height: 35px}
.itemD { background-color:blue; margin-top:auto; width: 80px;}
<div class="parentFlexBox">
<div class="itemA">A</div>
<div class="itemB">B</div>
<div class="itemC">C</div>
<div class="itemD">D</div>
</div>
Please run above code in full screen to see the issue
This might work for you:
HTML (add two invisible flex items)
<div class="parentFlexBox">
<div class="itemA">A</div>
<div class="itemB">B</div>
<div class="itemC">C</div>
<div class="itemD">D</div>
<div class="itemE">E</div><!-- invisible spacer item with 150px height -->
<div class="itemF">F</div><!-- invisible spacer item with 120px height -->
</div>
CSS
.parentFlexBox { justify-content: space-between; } /* changed from `center` */
.itemA { order: 1; } /* removed `margin-top: auto` */
.itemB { order: 2; }
.itemC { order: 3; }
.itemD { order: 5; height: 30px; } /* added `height` for centering calculation;
removed `margin-top:auto` */
.itemE {
order: -1;
flex: 0 0 150px; /* don't grow, don't shrink, remain at 150px height */
visibility: hidden;
margin-bottom: auto; /* stick to top of container */
}
.itemF {
order: 4;
flex: 0 1 120px; /* don't grow, shrink proportionally, start at 120px height */
visibility: hidden;
margin-top: auto; /* go south as much as possible (sticks to Item D) */
}
/* NOTE: Item D has height 30px. Item F has height 120px. Together they equal height of
Item E. Equally balanced on both ends, Items A, B & C are centered in the container. */
DEMO 1
I placed the spacer divs last in the mark-up to keep with the alphabetical ordering. If you prefer to list all divs (including spacers) in order, that would eliminate the need for the order property.
Also, in the demo, the code includes borders, in case you want to see the spacers at work. Just disable the visibility property.
Update (based on comment)
Nice, a couple of questions though: 1) Possible to make it so that BCD don't change height when resizing the window? 2) Possible to make the gray background extend to contain D when window is short? 3) Possible to do items E and F as pseudocode elements?
Question #1: Yes. Add flex: 0 0 <<absolute height>> to BCD. For instance, add flex: 0 0 50px to each item, which tells them to stay fixed at 50px height. (Also, remove the height property from each rule, to avoid any potential conflict with flex.)
Question #2: Yes. Instead of limiting the container to height: 100vh, use min-height: 100vh.
Question #3: Yes. Remove the E and F code from the HTML and CSS, and add this to the CSS:
.parentFlexBox::before {
content: '';
flex: 0 0 150px;
visibility: hidden;
margin-bottom: auto;
}
.parentFlexBox::after {
content: '';
flex: 0 1 100px;
visibility: hidden;
margin-top: auto;
order: 4;
}
DEMO 2

table-cell height is not fitting to content

I am using CSS tables to setup a basic grid for a page. The center cell of each row will contain content whereas the first and third "columns" will just be a background color.
The problem I am having has to do with table-cell height. Here is a jsfiddle showing the issue: http://jsfiddle.net/UQUA9/
/*** The essential CSS for the layout ***/
html, body {
height: 100%;
margin: 0pt;
}
.Frame {
display: table;
width: 100%;
}
html>/**/body .Frame {
height: 100%;
}
.Row {
display: table-row;
height: 1px;
overflow: hidden; /* commenting this out has no effect. */
}
html>body .Row.Expand {
height: auto; /* commenting this out has no effect. */
}
.Row div {
display: table-cell;
}
Note that in the HeaderRow, the ContentColumn has a large gap beneath the end of the text between it and the MenuRow. I don't understand why the table-cell is padding it out like that. As far as I can see, I don't have any padding or margin set that would account for this empty space. I went with CSS table specifically because it will autofit cell height to content and now it isn't working!
Here's a screen shot to illustrate. The extra grey is the problem. The cell should end on the line after the text but there is a bunch of empty grey. The pink MenuRow should be displayed right after the text in the HeaderRow.
I know I am missing something simple or obvious. Any hints are appreciated.

Dynamic width div auto resize to fit browser width?

I have several div with unknown width(dynamic width).
How can I auto resize these div to fit browser width?
For example, I have 5 div with difference width. If the browser width only able to fill up 3 div then those 3 div will auto resize to fit the browser width and the rest will display at second row.
How can I make it using html5 and css3. I know that a new feature flexbox in css3 but i am not sure whether I can deal with it.
You can play with the calss - value acording your request.
min/max width/height
see example demo jsFiddle
.grid {
display: box;
display: -webkit-flex;
display: flex;
}
.column {
padding: 20px;
}
.fluid {
box-flex: 1;
background: #ccc;
}
.fixed {
width: 100px;
background: red;
}​

An expanding middle in CSS

How would I go about designing a website which has a fixed height header and footer (attached to the top and bottom of the browser window) but an expanding middle. The scroll bars would be only for the middle (orange section in diagram) so that the rest of the page would never need to scroll. I have drawn a mock-up below to explain more clearly.
Ideally it needs to be entirely implemented in CSS and HTML (no javascript fiddles!). I've got quite far with this problem but I can't force the orange section to fill up the remaining space when it isn't full(whatever it's content) and start scrolling if it overflows.
I think this is what you want:
Live Demo (edit)
HTML:
<div id="header">Patrick</div>
<div id="content">..</div>
<div id="footer">Beardmore</div>
CSS:
html, body {
margin: 0;
padding: 0;
border: 0;
overflow: hidden
}
#header, #content, #footer {
position: absolute;
left: 0;
width: 100%
}
#header {
top: 0;
height: 100px;
background: #ccc
}
#content {
top: 100px;
bottom: 100px;
overflow-y: auto
}
#footer {
bottom: 0;
height: 100px;
background: #ccc
}
It's called StickyFooter or the "footer push" method. It's all over the web, but this is the best option I've found:
http://ryanfait.com/sticky-footer/
An old question, but flexbox has given us a super easy way to implement this pattern, a familiar variation on the 'Holy Grail' layout:
body {
/*set container to vertical (column) flex mode, ensure body is full height*/
display: flex;
min-height: 100vh;
flex-direction: column;
}
header, footer {
/*more or less equivalent to min-height:50px*/
flex-basis:50px
}
header {
background-color: #7AEE2D;
}
main {
background-color: #EBAE30;
/*tell main section to expand to fill available space, this is same as flex 1; or flex:1 1 auto;*/
flex-grow:1;
}
footer {
background-color: #34A4E7;
}
<header>header</header>
<main>main</main>
<footer>footer</footer>
A note about the syntax: I've used the "atomic" flexbox CSS properties here for simplicity, but in the wild you are more likely to run into the shorthand syntax using the flex keyword by itself. The default values for the 3 properties you can set on flex items (children of a display:flex container) are:
Initial value as each of the properties of the shorthand: flex-grow: 0
flex-shrink: 1 flex-basis: auto
Using flex, there are multiple ways to compose these properties, specifying one, two, or three values, and those values can by keywords, unit lengths (2px), or unitless grow/shrink ratios 2. Many different "overloads" are available, depending on your arguments.
For example, flex-basis:50px could've been flex:50px, flex:0 1 50px, and flex-grow:1 could have been flex 1; or flex:1 1 auto;. It's still not as bad as some other CSS shorthands I can think of (position, I'm looking at you). The 'flex' shorthand syntax MDN page has more details.