Absolute and relative positioning at the same time in CSS [closed] - css

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
Basically I have 3 divs:
<div></div>
<div></div>
<div></div>
clicking on 1st div toggles visibility of 2nd div
what I want is that 3rd div would take up all the remaining space but no more. In case of large 3rd div content I want scrollbar only on 3rd div, not whole page.
I have JS solution. So any pure CSS would be highly appreciated.

Here is one approach that involves using a combination of CSS table-cells and absolute positioning.
Create a CSS table as the top level container .main, and define three display: table-row containers .head, .extra and .content.
Within .content, nest a display: table-cell element .wrap and set position: relative. Within .wrap, use absolute positioning to fit a .scroller container that will hold the content.
If you hide the .extra block, the .content will stretch vertically to take up the remaining space.
html, body {
height: 100%;
margin: 0;
}
.main {
border: 1px dotted gray;
width: 100%;
height: 100%;
box-sizing: border-box;
display: table;
overflow: hidden;
}
.head {
display: table-row;
height: 50px;
background-color: beige;
}
.extra {
display: table-row;
/* display: none; */
height: 100px;
background-color: tan;
}
.content {
display: table-row;
background-color: lightblue;
height: auto;
}
.content .wrap {
display: table-cell;
height: auto;
position: relative;
}
.scroller {
overflow: auto;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
<div class="main">
<div class="head">head</div>
<div class="extra">extra</div>
<div class="content"><div class="wrap"><div class="scroller">
<p>Scrolling div...</p>
<p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque bibendum imperdiet metus ac elementum. Donec viverra porttitor velit, ut eleifend nulla porttitor quis. Donec placerat, leo ac volutpat pellentesque, elit mauris aliquet metus, sit amet dictum enim augue consequat elit. Pellentesque eu diam a sem ornare tristique. Sed sollicitudin elementum nibh, eget tincidunt sem rhoncus at. Morbi cursus ornare dolor, vel tempus leo blandit ut. Donec at dictum eros. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Integer faucibus tellus in aliquet accumsan. Nam scelerisque ante eros, et tempus dolor mollis nec. Cras in mauris ac orci hendrerit venenatis. Nunc porta nisi eu odio feugiat, sed fermentum odio posuere. Vivamus luctus dui sit amet lobortis dignissim. Nulla feugiat est lacinia est porta porttitor. </p>
</div>
</div>
</div>
</div>

If you know that there will only be three divs, you could just control the height and change it from 33% to 66% when the second div collapses, and using css transition to make the animation.

Related

Positioning divs inside a parent div

What would be a good way of positioning two divs (green and yellow) inside a parent div (blue outline) so that it looks like in the second drawing below? (First drawing is how divs stack by default).
I have a number of these blue divs whose green divs are variable height (different amount of text) and the yellow divs are always the same.
I want the yellow divs to always be at the bottom of the container.
Edit: Forgot to mention that all my blue parent divs should be same height
I tried positioning yellow divs as position:absolute with bottom:0 and blue divs to position:relative but this didn't work because then if one of the green divs has a lot of text it will run into and text will overlap the yellow div;
Blue parent divs are set to height:100%
What am I missing here?
Sorry if newbie question, I'm just getting into CSS and UI design.
You can make use of the flexbox properties. I just set the height for snippet purpose. You can alter the height based on your preference and check the text.
.parent {
display: flex; /* Activate Flexbox container */
flex-direction: column; /* To set the main axis in block direction */
justify-content: space-between; /* Align them distributed equally from first to last */
height: 150px;
width: 200px;
border: 5px solid #00A2E8;
}
.child1 {
background: green;
height: 25%;
}
.child2 {
background: yellow;
height: 25%;
}
<div class="parent">
<div class="child1"></div>
<div class="child2"></div>
</div>
Assuming the yellow div is a fixed height this is pretty easy
.parent {
/*Children will be positioned relative to this*/
position: relative;
/*Allow to be > 100% if content requies it*/
/*154 = height of yellow div + border*/
min-height: calc(100vh - 154px);
/*Height of yellow div*/
padding-bottom: 150px;
border: 2px solid blue;
/*The following is purely for demo purposes*/
width: 25%;
display: inline-block;
vertical-align: top;
}
/*The Green div is pretty standard*/
.green {
background-color: green;
color: white;
}
.yellow {
background-color: yellow;
/*Fixed height*/
height: 150px;
/*Set to postion absolute - relative to parent*/
position: absolute;
/*Set bottom to bottom of parent*/
bottom: 0;
/*Giv it a width*/
width: 100%
}
/*Tweak margins for first and last paragrpahs*/
.green p:first-of-type {
margin-top: 0;
}
.green p:last-of-type {
margin-bottom: 0;
}
body {
margin: 0
}
<div class="parent">
<div class="green">
<p>Some text</p>
</div>
<div class="yellow">
</div>
</div>
<div class="parent">
<div class="green">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque nibh justo, tincidunt sed elementum id, dictum quis nunc. Pellentesque et sodales mi.
</p>
</div>
<div class="yellow">
</div>
</div>
<div class="parent">
<div class="green">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque nibh justo, tincidunt sed elementum id, dictum quis nunc. Pellentesque et sodales mi. Mauris luctus leo ac eros tempor, quis gravida leo pellentesque. Etiam odio nisl, lobortis ut elit
ut, mollis eleifend ex. Etiam et risus at diam iaculis sagittis. Pellentesque porttitor odio suscipit, fringilla odio et, laoreet lectus. Nunc tincidunt ultrices condimentum. Nulla sit amet ante posuere, convallis justo vitae, facilisis orci. In
congue egestas diam vitae fermentum. Vivamus efficitur ligula sed tincidunt blandit. Etiam feugiat egestas sem ut pellentesque. Nulla ac dui bibendum, finibus mi vitae, suscipit quam.
</p>
<p>
Etiam pellentesque, diam eget condimentum rutrum, odio orci ultrices eros, in tincidunt magna tortor id augue. Nunc vitae dolor a risus egestas hendrerit a et augue. Pellentesque rhoncus lacus elit, at laoreet dolor pretium condimentum. Sed egestas placerat
ante, in convallis arcu facilisis id. Sed nec rutrum velit. Fusce eget sem turpis. Nulla facilisi. Nam suscipit ante leo, non viverra mauris ultrices id. Donec dui ligula, aliquet sed risus vitae, mollis posuere est. Aenean elementum, libero quis
fermentum dictum, sem lacus volutpat orci, quis rutrum ante odio eleifend risus. Nullam placerat et lacus in sagittis. Suspendisse potenti. Maecenas ullamcorper cursus ligula sit amet ullamcorper.
</p>
</div>
<div class="yellow">
</div>
</div>
If you use flex this will be supereasy -:
.container {
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
height: 500px;
border: 2px solid blue;
}
.green {
flex: 1;
width: 100%;
background: green;
}
.white {
flex: 1;
width: 100%;
background: white;
}
.yellow {
flex: 1;
width: 100%;
background: blue;
}
<div class="container">
<div class="green"></div>
<div class="white"></div>
<div class="yellow"></div>
</div>
In this case we have given flex: 1 for all the divs, so the ratio
of all the 3 divs is 1:1:1.
If you give the value of flex to be 1,2,1 then the ratio will be
1:2:1 i.e. 25%,50%,25% of the total height of container.
Also we need to define height for outer div so that ratio distribution can happen.

Troubles with CSS height in percentage

It's a bit difficult for me to explain my problem, so much better to just show an example (check the JSFiddle):
#contacts {
position: fixed;
bottom: 0;
width: 100%;
max-height: 75%;
}
#contacts .tab-content {
height: 100%;
overflow: scroll;
}
JSFiddle no scroll
As you see, there's a tab fixed on the bottom which toggles a panel (I'm using Bootstrap 3). The content of the panel is dynamically generated, so I need the panel to increase its height as the content is generated, up to a 75% of the page's height (not to cover it all).
Now, when the content is too much, I need an inner scrollbar; as you can see, the scrollbar is there, but it's not working, because the #contacts div has no specific height, so the .tab-content's "height: 100%" is not working.
If I try using "overflow: scroll" on #contacts instead of .tab-content, it works:
JSFiddle scrolls label too
But the problem, now, is that the scrollbar also scrolls the tab label, and that it's outside of the .tab-content, so when I click on it the div loses focus and the tab closes.
Any idea how to solve this? Thanks!
Proof of Concept Solution
I boiled down the design problem to the basics (without Bootstrap).
The .fixed-wrapper is pinned to the bottom of the page using position: fixed, and apply overflow-y: scroll to enable scrolling.
The .header tab element is also positioned fixed, but the trick is to set the bottom offset to the same value as the max-height value of .fixed-wrapper, 60% in this example.
Then you toggle the content, you need to adjust the following:
.fixed-wrapper { max-height: 0;}
.header { bottom: 0;}
.scroll-panel { display: none;}
If you have an .active class to distinguish the display state, your CSS might look like:
.fixed-wrapper.active { max-height: 60%;}
.fixed-wrapper.active .header { bottom: 60%;}
.fixed-wrapper.active .scroll-panel { display: bottom;}
When applying this to a Bootstrap layout, make sure that your selectors are specific enough so that the Bootstrap classes do not override the key rules shown above.
Note: There is a minor limitation to this solution. If the content is insufficiently tall to force scrolling, then the header element may hang at the
60% position even though the .scroll-panel does not reach the max-height. You may need some JavaScript to take care of that.
body {
margin: 0;
}
p {
line-height: 2.0;
}
.fixed-wrapper {
background-color: lightblue;
max-height: 60%;
position: fixed;
bottom: 0;
overflow-y: scroll;
}
.header {
background-color: lightgray;
position: fixed;
bottom: 60%;
right: 0;
margin-right: 50px;
width: auto;
}
.scroll-panel {
background-color: lightblue;
display: block;
}
<div class="fixed-wrapper">
<div class="header">header or tab...</div>
<div class="scroll-panel">
<p>Some content...</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer facilisis velit ut neque tempor quis cursus tortor suscipit. Curabitur rutrum magna vitae arcu pharetra eget cursus ante accumsan. Nunc commodo malesuada adipiscing. Pellentesque consequat laoreet sagittis. Sed sit amet erat augue. Morbi consectetur, elit quis iaculis cursus, mauris nulla hendrerit augue, ut faucibus elit sapien vitae justo. In a ipsum malesuada nulla rutrum luctus. Donec a enim sapien. Sed ultrices ligula ac neque vulputate luctus. Suspendisse pretium pretium felis, in aliquet risus fringilla at. Nunc cursus sagittis commodo.</p> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer facilisis velit ut neque tempor quis cursus tortor suscipit. Curabitur rutrum magna vitae arcu pharetra eget cursus ante accumsan. Nunc commodo malesuada adipiscing. Pellentesque consequat laoreet sagittis. Sed sit amet erat augue. Morbi consectetur, elit quis iaculis cursus, mauris nulla hendrerit augue, ut faucibus elit sapien vitae justo. In a ipsum malesuada nulla rutrum luctus. Donec a enim sapien. Sed ultrices ligula ac neque vulputate luctus. Suspendisse pretium pretium felis, in aliquet risus fringilla at. Nunc cursus sagittis commodo.</p>
</div>
</div>
Ok so I looked at it again and it is indeed a pain, but this seems to work (a bit ugly though): Fiddle
#contacts {
position: fixed;
bottom: 0;
width: 100%;
max-height: 75%;
overflow-y: hidden;
}
#contacts .tab-content {
background-color: #ccc;
}
.tab-pane {
height:300px;
overflow-y:scroll;
}
#contacts ul li {
position: relative;
float: right;
margin-right: 15%;
}
#contacts > ul > li > a {
background-color: #ccc;
}

Make a div containing CSS columns have unlimited width

Imagine a very common <header><article><footer> layout, where the header and footer are fixed heights and the article gets as tall as needed (the page scrolls vertically to accommodate). That's like most web pages.
What I'm trying to get is a layout just like that, but on its side so the article gets as wide as needed, and the page scrolls horizontally:
My initial attempts used flexbox:
Here is my first attempt on jsFiddle.
Relevant CSS:
body {
display: flex;
position: absolute;
height: 100%;
}
header {
background: green;
width: 400px;
flex: none;
}
article {
background: #CCC;
-webkit-columns: 235px auto;
columns: 235px auto;
-webkit-column-gap: 0;
column-gap: 0;
}
footer {
background: yellow;
width: 450px;
flex: none;
}
But I'm moving away from that as I try other things, like in this fiddle, which is a little closer. The problem with this attempt is that the article width is constrained to 100% of the viewport width, even though the text flows over to the right! (My article uses CSS columns which is absolutely important to my layout.)
My requirements are:
Header, Article, Footer to be 100% height (done)
Header to be 400px wide (done) and to left of content (done)
Footer to be 450px wide (done) and to right of the article (how?)
Article to be as wide as it needs to be without overlapping footer (how?)
So, I need help with the bolded goals. What can I do to keep the article from overlapping the footer to its right? Are there other ways to lay out this page so that the article width expands as the content does?
Should work in Chrome, Firefox, and Safari (IE and Opera a plus, but not necessary)
Preferably no JavaScript (or CSS features likely to be dropped from the spec)
Simple, clean CSS is ideal
I've been working on this all afternoon and without JS it seems pretty impossible. I've also fiddled with #Grily's solution and I think I nailed it in Chrome at least.
Solution 1 Works on Firefox, Chrome and IE
However I got this to work, sort of. It's not completely to spec.
HTML
<div id="DIV-1">Header </div>
.. in the Fiddle there's a lot of "Lorum ipsum here"
<div id="DIV-3">Footer </div>
CSS
#media only screen
and (orientation : landscape) {
body {
position: absolute;
display: block;
box-sizing: border-box;
white-space: normal;
-webkit-columns: 235px auto;
-moz-columns: 235px auto;
columns: 235px auto;
-webkit-column-gap: 0;
-moz-column-gap: 0;
column-gap: 0;
height: 100%;
float: left;
width: calc(100% + 450px);
min-width: -webkit-min-content;
padding-left: 400px;
}
#DIV-1{
position: absolute;
left: 0px;
box-sizing: border-box;
background-color: #2693FF;
height: 100%;
width: 400px;
float: left;
}
#DIV-3 {
position: relative;
float: right;
left: 205px;
box-sizing: border-box;
background-color: #FF7373;
height: 100%;
width: 450px;
-webkit-column-span: all;
-moz-column-span: all;
column-span: all;
-webkit-column-break-inside: avoid;
page-break-inside: avoid;
break-inside: avoid;
}
}
I've put the content container the columns directly into the body. (Can still be a div).
width: calc(100% + 450px);
min-width: -webkit-min-content;
This bit actually (by magic) forces the browser to recognize that the body has a width that is broader than the viewport. The positioning of the header is simple. absolute and add padding to the body and it's in place. The content now flows nicely to the right. Exception is the footer. I got it in the right position on it's own by using column-span: all. Firefox is going it's own way with this and actually renders it correctly. Chrome and IE render the column inline and only the width of the column. That's the drawback of this approach.
I hope you can do something with it or somebody else could improve this so it actually appends the footer at the end of the page without shrinking it to the column's width.
The Fiddle: http://jsfiddle.net/5dtq47m3/
Solution 2 - Works on Chrome
Edited the work of Grily.
HTML
<header>
<h1>Article Title (width 400)</h1>
</header>
<article>
........
</article>
<footer>Footer should be 450px wide and appear to the right of everything else.</footer>
CSS
* {
padding: 0;
margin: 0;
}
body {
display: flex;
position: absolute;
height: 100%;
}
header {
background: green;
width: 400px;
flex: none;
float: left;
}
article {
background: #CCC;
-webkit-columns: 235px auto;
columns: 235px auto;
-webkit-column-gap: 0;
column-gap: 0;
color: rgba(0, 0, 0, .75);
flex:none; /*added*/
width: calc(100% + 10px); /*added*/
max-width: -webkit-max-content; /*added*/
}
article p {
padding: .2em 15px;
text-indent: 1em;
hyphens: auto;
}
footer {
background: yellow;
width: 450px;
flex: none;
float: right; /*added*/
}
http://jsfiddle.net/w4wzf9n6/8/
I have the flex basics here: http://jsfiddle.net/hexalys/w4wzf9n6/16/ which is the cleanest theoretical css.
This places the footer to the right of the article and the article doesn't overlap with the footer. Best visible in Webkit/Blink with calculation issues on the text content width interpreted by Flex.
In an ideal world, Flexbox would know what to do with the columns and calculate the auto width of the article flex item. But because 1. This isn't specced yet; 2. Flex still has existing issues to be resolved; And 3. CSS Columns are still quite buggy and unstable. Webkit and Firefox handle his both differently and wrong. For Webkit a flex auto width is that of the <p> element on one line, and for FF/IE it is the size of one column only. So it's quite a dead end, and need solving by the W3C specs before this would work. I tried to wrap article, but it doesn't seem to help that cause.
Meanwhile if you know the constraint of the viewport height and the amount of text on the server side, you could use a JS fallback to give the article element a flex width before DOMContentLoaded. (See my later comment for a partial Webkit/Blink polyfill)
Update: The multi-column issue is a know problem back from 2007. This case was added as reference on the CSS Working Group wiki page listing current multicolumn issues
Here's a solution that works on webkit browsers, Firefox, and IE:
// JS to work around the CSS column bug where the width
// is not properly calculated by the browser. We have a
// float:right marker at the end of the article. Set the
// width of the article to be where the marker is.
function resize()
{
var article = document.querySelector("article"),
marker = document.querySelector("endmarker");
article.style.width = (marker.offsetLeft) + "px";
}
window.addEventListener("resize", resize);
resize();
* { padding: 0; margin: 0; }
holder {
position: absolute;
top: 0; left: 0;
height: 100%;
background: #fed;
white-space: nowrap;
}
header,
article,
footer {
position: relative;
display: inline-block;
height: 100%;
vertical-align: top;
white-space: normal;
}
header {
background: green;
width: 400px;
}
endmarker {
position: relative;
display: block;
float: right;
width: 10px;
height: 10px;
background: red;
}
article {
background: #CCC;
-webkit-columns: 235px auto;
-moz-columns: 235px auto;
columns: 235px auto;
-webkit-column-fill: auto;
-moz-column-fill: auto;
column-fill: auto;
-webkit-column-gap: 0;
-moz-column-gap: 0;
column-gap: 0;
}
article p {
padding: .2em 15px;
text-indent: 1em;
hyphens: auto;
}
footer {
background: yellow;
width: 450px;
}
<holder>
<header>
<h1>Article Title (width 400)</h1>
</header>
<article>
<p><b>Article should stretch as wide as it needs to be. Horizontal scrolling only. Preferably, columns aren't sized according to viewport width. Seeing partial column helps the user know they can scroll left.</b>
</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed commodo venenatis efficitur. Nam vel ultricies urna, non auctor lorem. Suspendisse sodales, nunc eu pharetra ornare, elit quam scelerisque ex, id congue orci lectus eget turpis. Ut consequat nisi et erat efficitur faucibus. Maecenas laoreet magna nec odio porta, et consequat leo rhoncus. In imperdiet pellentesque justo eu pellentesque. Curabitur ut ante tristique, placerat est porta, porttitor ligula. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed scelerisque est vitae orci elementum, et vehicula quam lacinia. Vivamus vestibulum metus quis dui dictum vehicula. Mauris et tempor libero.</p>
<p>Sed lorem quam, feugiat sit amet vehicula non, ultricies quis quam. Ut lobortis leo ac ex facilisis, vel elementum ante feugiat. Quisque efficitur tellus sed sodales dictum. Mauris sed justo dictum, finibus velit id, pulvinar mi. Phasellus mi augue, finibus ut vestibulum et, volutpat id sapien. Sed feugiat eleifend augue, ut commodo nulla bibendum ac. Nullam quis posuere lectus. Curabitur dictum quam id massa finibus blandit. Nam malesuada metus ut massa ullamcorper luctus. Curabitur vitae dictum orci, a finibus sapien. Maecenas eget nisl tempus, pharetra enim eget, tempor urna. Suspendisse viverra felis bibendum neque rhoncus, id eleifend tortor sodales. Suspendisse sed magna pulvinar, laoreet turpis nec, ultrices enim. Vivamus at auctor arcu. Nunc vitae suscipit tellus. Etiam ut accumsan arcu.</p>
<p>Morbi faucibus, mauris sed blandit ultrices, turpis turpis dapibus quam, quis consectetur erat nibh cursus magna. Donec quis ullamcorper quam, a facilisis leo. Phasellus ut mauris eget risus ultrices lobortis. Pellentesque semper ante eu vehicula pharetra. Vestibulum congue orci non felis vehicula volutpat. Praesent vel euismod ligula. Sed vitae placerat ipsum, a hendrerit felis. Mauris vitae fermentum nunc, non tincidunt magna. Fusce nibh ex, porta sed ante ut, dapibus maximus urna. Nulla tristique magna ipsum, at sodales ipsum feugiat a. Mauris convallis mi vel arcu vehicula elementum. Aliquam aliquet hendrerit lectus, congue auctor ipsum sodales vitae. Phasellus congue, ex non viverra cursus, nunc est fermentum dui, ac tincidunt turpis mauris a tellus. Curabitur sollicitudin condimentum mauris consectetur tincidunt. Morbi vulputate ac augue ut maximus.</p>
<p>Nulla in auctor ligula. In euismod volutpat ex a eleifend. Sed eu elit et nulla faucibus fringilla. Sed posuere metus in elit gravida pharetra. Vivamus a ultricies ipsum. Mauris mollis est nisi, a convallis est iaculis id. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Etiam tincidunt blandit metus nec sagittis. Sed faucibus non urna in ullamcorper. Sed feugiat, tellus ut feugiat mollis, ligula neque molestie augue, vitae mattis ligula eros eget augue. Curabitur finibus sodales metus ac finibus. Sed id mollis ante. Phasellus vitae purus vel risus pulvinar aliquet. Vestibulum vitae elementum felis.</p>
<p>Nam ipsum ipsum, consequat in dictum vitae, malesuada eget est. Phasellus elementum lacinia maximus. Maecenas dictum neque ligula, et congue mauris venenatis eu. Pellentesque pretium tortor nec ligula rutrum, a aliquet eros aliquam. Etiam euismod varius ipsum, id molestie massa. Quisque elementum lacus at ipsum egestas facilisis. Maecenas arcu risus, euismod ac lacus ac, euismod dictum nunc. Aenean non felis aliquet mi tincidunt bibendum. Curabitur ultricies ullamcorper gravida. In pretium nibh non eleifend egestas. Cum sociis natoquenatibus et magnis dis parturient montes, nascetur ridiculus mus. Proin auctor lacus erat, sit amet vestibulum lorem mattis in. Aenean dapibus at risus ac lacinia. Vivamus fringilla nulla diam, vel facilisis magna mollis maximus. Sed quis dolor tempor magna pharetra scelerisque. Nam velit felis, mollis sit amet risus et, imperdiet interdum nibh.</p>
<p>END OF ARTICLE</p>
<endmarker></endmarker>
</article>
<footer>Footer should be 450px wide and appear to the right of everything else.</footer>
</holder>
http://jsfiddle.net/jmhh56g2/2/
All browsers have a bug with column layout and how they calculate the width of the element with columns. So unfortunately, a tiny bit of JS is needed to set the width. I know the requirement said "preferably no javascript", but this is fairly minimal and it works on all browsers that support CSS columns.
Quick overview:
Put the entire content in an absolutely positioned div (<holder>) that is 100% height. This pulls the content out of the main body flow and prevents the body and viewport width from doing crazy things.
Set white-space: nowrap on <holder> and normal for all other elements. This forces the header,article, and footer to align horizontally, while allowing the text inside them to flow normally.
Set all elements to be position: relative (needed for offsetWidth)
Create a little marker element at the article that is float:right. This is used to calculate the correct width.
A tiny bit of js to watch the window resize event and recalculate the proper width for the article.
Flexbox does indeed work for this, but you need to add a few more things.
Add the following CSS:
article {
display: flex;
}
To make each paragraph inside the article tag the same width, add:
article p {
flex: 1;
}
A quick fix for the width (and height) of the footer, add:
footer {
display: table;
height: 100%;
}
Edit:
Been playing around with it a little, but didn't figure it out yet.
I'll just leave the code here, but it's incorrect.
html {
height: 100vh;
}
body {
display: -webkit-box;
height: 100%;
}
header {
background: green;
width: 400px;
flex: none;
}
article {
background: #CCC;
-webkit-columns: 235px auto;
columns: 235px auto;
-webkit-column-gap: 0;
column-gap: 0;
color: rgba(0, 0, 0, .75);
height: 100%;
}
footer {
background: yellow;
width: 450px;
display: table;
height: 100%;
}
The simple answer is to set the overflow-x and overflow-y on the body, and then display: inline-block the elements inside. Here's the code:
body {
height: 500px; /* just for demo */
white-space: nowrap;
overflow-x: scroll;
overflow-y: hidden;
}
header,
article,
footer,
.box {
display: inline-block;
height: 500px; /* just for demo */
}
header,
footer {
width: 200px;
background: #666;
}
.box {
width: 300px; /* just for demo */
background: #ccc;
}
<header>header</header>
<article>
<div class="box">stuff</div>
<div class="box">stuff</div>
<div class="box">stuff</div>
<div class="box">stuff</div>
<div class="box">stuff</div>
<div class="box">stuff</div>
<div class="box">stuff</div>
</article>
<footer>footer</footer>
Here is a demo
There is a lot to be said for flex. I suggest bookmarking this link: CSS-TRICKS A Complete guide to FlexBox
Regarding the columns - column width is a minimum width, not a forced value so you will never see a partial column within <article> tags
Css Changes as noted and fiddle following:
article {
background: #CCC;
-webkit-columns: 235px auto;
columns: 235px auto;
-webkit-column-gap: 0;
column-gap: 0;
color: rgba(0, 0, 0, .75);
/* Added */
overflow:hidden;
overflow-x: scroll;
}
footer {
background: yellow;
/* Changed */
min-width: 450px;
display: block;
}
EDIT: I updated my fiddle; There are some limitations being imposed by Fiddle in that the results are displayed in an iframe that limit the width and height to 100% of the results display quadrant so you don't really get to see true browser results.
The solution in this edited fiddle does not use Flex, but a combination of inline-blocks with some white-space management. This is as close as I could come with the time I had. Hope it helps.
Updated: FIDDLE
Possible solution.
The CSS:
<style type="text/css">
* {
margin:0;
padding:0;
}
html {
height:100%;
}
body {
display:table;
height:100%;
width:100%;
}
header {
background:green;
display:table-cell;
vertical-align:top;
width:400px;
}
article {
background:#CCC;
color:rgba(0, 0, 0, .75);
display:table-cell;
}
article div {
-moz-column-gap:0;
-moz-columns:235px auto;
-webkit-column-gap:0;
-webkit-columns:235px auto;
column-gap:0;
columns:235px auto;
height:100%;
max-height:1vh;
min-height:100%;
overflow-x:scroll;
}
article p {
hyphens:auto;
padding:.2em 15px;
text-indent:1em;
}
footer {
background:yellow;
display:table-cell;
vertical-align:top;
width:450px;
}
</style>
The HTML:
<header>
<h1>Article Title (width 400)</h1>
</header>
<article>
<div>
<p>Article Text</p>
</div>
</article>
<footer>
Footer should be 450px wide and appear to the right of everything else.
</footer>
Man I thought I had it... It works if the window is a particular height. If you change the size of the output pane, the content doesn't fit evenly. Works the same in both Firefox and Chrome, wanted to put it out there to see if it helps someone get closer to a solution.
http://jsfiddle.net/ryanwheale/bbhmkLw5/
HTML:
<article>
<header></header>
<section></section>
<footer></footer>
</article>
CSS:
html, body, article, header, section, footer {
height: 100%;
margin: 0;
}
html, body {
background: red;
width: calc(100% + 850px);
}
article {
white-space: nowrap;
background: blue;
}
article > * {
white-space: normal;
display: inline-block;
vertical-align: top;
}
header {
background: green;
width: 400px;
}
section {
background: grey;
-webkit-columns: 2000 235px;
-moz-columns: 2000 235px;
columns: 2000 235px;
-moz-column-fill: auto;
}
footer {
background: yellow;
width: 450px;
}
Check this out!
Some JavaScript code is needed to calculate dynamic width, otherwise overall structure is simple and will work with almost all major browser (didn't checked JS, but that will be easy change, "in case"!).
You can also check on JSFiddle here.
var header = document.getElementsByTagName('header')[0].offsetWidth;
var article = document.getElementsByTagName('article')[0].children[0].offsetWidth * document.getElementsByTagName('article')[0].children.length;
var footer = document.getElementsByTagName('footer')[0].offsetWidth;
document.getElementsByTagName('html')[0].style.width = header + article + footer + 'px';
html,body,header,article,article p,footer{
margin:0px;
padding:0px;
height:100%;
}
html{ width: 100%; }
body{ width: auto; }
header, footer{
width: 200px;
float: left;
}
header{ background-color: green; }
footer{ background-color:yellow; }
article{
display:block;
width: auto;
float: left;
}
article p{
border:1px solid red;
width: 200px;
float: left;
display:inline-block;
}
<header>
<h1>Article Title</h1>
</header>
<article>
<p><b>Article should stretch as wide as it needs to be. Horizontal scrolling only. Preferably, columns aren't sized according to viewport width. Seeing partial column helps the user know they can scroll left.</b></p>
<p><b>Article should stretch as wide as it needs to be. Horizontal scrolling only. Preferably, columns aren't sized according to viewport width. Seeing partial column helps the user know they can scroll left.</b></p>
<p><b>Article should stretch as wide as it needs to be. Horizontal scrolling only. Preferably, columns aren't sized according to viewport width. Seeing partial column helps the user know they can scroll left.</b></p>
<p><b>Article should stretch as wide as it needs to be. Horizontal scrolling only. Preferably, columns aren't sized according to viewport width. Seeing partial column helps the user know they can scroll left.</b></p>
<p><b>Article should stretch as wide as it needs to be. Horizontal scrolling only. Preferably, columns aren't sized according to viewport width. Seeing partial column helps the user know they can scroll left.</b></p>
<p><b>Article should stretch as wide as it needs to be. Horizontal scrolling only. Preferably, columns aren't sized according to viewport width. Seeing partial column helps the user know they can scroll left.</b></p>
<p><b>Article should stretch as wide as it needs to be. Horizontal scrolling only. Preferably, columns aren't sized according to viewport width. Seeing partial column helps the user know they can scroll left.</b></p>
<p><b>Article should stretch as wide as it needs to be. Horizontal scrolling only. Preferably, columns aren't sized according to viewport width. Seeing partial column helps the user know they can scroll left.</b></p>
<p><b>Article should stretch as wide as it needs to be. Horizontal scrolling only. Preferably, columns aren't sized according to viewport width. Seeing partial column helps the user know they can scroll left.</b></p>
</article>
<footer>
Footer should be 450px wide and appear to the right of everything else.
</footer>
You should use table css then it's easy - otherwise it's pain in the butt
Here is a working example: http://jsfiddle.net/y60zy7fp/1/
The main difference is removing flex and then wrapping everything in 1 .layout and 1 more div for table and table-row, and first element in div in .layout will become column this is css:
.layout {
display: table;
}
.layout > div {
display: table-row;
}
.layout > div > * {
display: table-cell;
}
update:
The article needs to have set width for the scroll to become horizontal.
In my example it's 200%.
example: http://jsfiddle.net/n3okxq94/7/
Why it has to have width? Because the width of a paragraph is the size of the container. And you're asking the container to set the width according to paragraph which has width: auto
You can add white-space: nowrap on article but that makes all text one line http://jsfiddle.net/n3okxq94/10/
finished? http://jsfiddle.net/n3okxq94/8/
You could put inside of the article something like at least one <p style="width: 1000px;">and that way you could have width per-article
How about this simple sultion below using very simple CSS and HTML?
html, body {width:100%; height:100%; min-height:100%; margin:0; padding:0;}
article {width:100%; height:100%; min-height:100%;}
header {width:400px; float:left; background:red; height:100%; min-height:100%;}
section {width:auto; display:block; background:blue; height:100%; min-height:100%; padding-right:450px;}
footer {width:450px; position:absolute; top:0; right:0; background:green; height:100%; min-height:100%;}
<article>
<header>content</header>
<section>content</section>
<footer>content</footer>
</article>
Hi Matt just try it me be it help full sorry for i can't make the live demo.
First download this jQuery library http://manos.malihu.gr/jquery-custom-content-scroller/ and css and js file in your code as lik.
<link rel="stylesheet" href="../jquery.mCustomScrollbar.css">
<style>
* {
padding: 0;
margin: 0;
}
html, body {
height: 100%;
width:auto;
display:block;
white-space:nowrap;
}
header, article, footer {
float: left;
height:100%;
vertical-align:top;
white-space:normal;
}
header {
background: green;
width: 250px;
padding: 0px 15px;
}
article {
background: #CCC;
color: rgba(0, 0, 0, .75);
width: 100%;
padding-right: 20px;
}
article p {
padding: .2em 15px;
text-indent: 1em;
hyphens: auto;
}
footer {
background: yellow;
width: 250px;
padding: 0px 15px;
}
.showcase #content-6.horizontal-images.content{
padding: 10px 0 5px 0;
background-color: #444;
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAYAAACp8Z5+AAAAG0lEQVQIW2NkYGA4A8QmQAwGjDAGNgGwSgwVAFVOAgV/1mwxAAAAAElFTkSuQmCC");
}
.showcase #content-6.horizontal-images.content .mCSB_scrollTools{
margin-left: 10px;
margin-right: 10px;
}
</style>
<body>
<header>
<h1>Article Title (width 400)</h1>
</header>
<article>
<p><b>Article should stretch as wide as it needs to be. Horizontal scrolling only. Preferably, columns aren't sized according to viewport width. Seeing partial column helps the user know they can scroll left.</b>
</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed commodo venenatis efficitur. Nam vel ultricies urna, non auctor lorem. Suspendisse sodales, nunc eu pharetra ornare, elit quam scelerisque ex, id congue orci lectus eget turpis. Ut consequat nisi et erat efficitur faucibus. Maecenas laoreet magna nec odio porta, et consequat leo rhoncus. In imperdiet pellentesque justo eu pellentesque. Curabitur ut ante tristique, placerat est porta, porttitor ligula. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed scelerisque est vitae orci elementum, et vehicula quam lacinia. Vivamus vestibulum metus quis dui dictum vehicula. Mauris et tempor libero.</p>
<p>Sed lorem quam, feugiat sit amet vehicula non, ultricies quis quam. Ut lobortis leo ac ex facilisis, vel elementum ante feugiat. Quisque efficitur tellus sed sodales dictum. Mauris sed justo dictum, finibus velit id, pulvinar mi. Phasellus mi augue, finibus ut vestibulum et, volutpat id sapien. Sed feugiat eleifend augue, ut commodo nulla bibendum ac. Nullam quis posuere lectus. Curabitur dictum quam id massa finibus blandit. Nam malesuada metus ut massa ullamcorper luctus. Curabitur vitae dictum orci, a finibus sapien. Maecenas eget nisl tempus, pharetra enim eget, tempor urna. Suspendisse viverra felis bibendum neque rhoncus, id eleifend tortor sodales. Suspendisse sed magna pulvinar, laoreet turpis nec, ultrices enim. Vivamus at auctor arcu. Nunc vitae suscipit tellus. Etiam ut accumsan arcu.</p>
<p>Morbi faucibus, mauris sed blandit ultrices, turpis turpis dapibus quam, quis consectetur erat nibh cursus magna. Donec quis ullamcorper quam, a facilisis leo. Phasellus ut mauris eget risus ultrices lobortis. Pellentesque semper ante eu vehicula pharetra. Vestibulum congue orci non felis vehicula volutpat. Praesent vel euismod ligula. Sed vitae placerat ipsum, a hendrerit felis. Mauris vitae fermentum nunc, non tincidunt magna. Fusce nibh ex, porta sed ante ut, dapibus maximus urna. Nulla tristique magna ipsum, at sodales ipsum feugiat a. Mauris convallis mi vel arcu vehicula elementum. Aliquam aliquet hendrerit lectus, congue auctor ipsum sodales vitae. Phasellus congue, ex non viverra cursus, nunc est fermentum dui, ac tincidunt turpis mauris a tellus. Curabitur sollicitudin condimentum mauris consectetur tincidunt. Morbi vulputate ac augue ut maximus.</p>
<p>Nulla in auctor ligula. In euismod volutpat ex a eleifend. Sed eu elit et nulla faucibus fringilla. Sed posuere metus in elit gravida pharetra. Vivamus a ultricies ipsum. Mauris mollis est nisi, a convallis est iaculis id. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Etiam tincidunt blandit metus nec sagittis. Sed faucibus non urna in ullamcorper. Sed feugiat, tellus ut feugiat mollis, ligula neque molestie augue, vitae mattis ligula eros eget augue. Curabitur finibus sodales metus ac finibus. Sed id mollis ante. Phasellus vitae purus vel risus pulvinar aliquet. Vestibulum vitae elementum felis.</p>
<p>Nam ipsum ipsum, consequat in dictum vitae, malesuada eget est. Phasellus elementum lacinia maximus. Maecenas dictum neque ligula, et congue mauris venenatis eu. Pellentesque pretium tortor nec ligula rutrum, a aliquet eros aliquam. Etiam euismod varius ipsum, id molestie massa. Quisque elementum lacus at ipsum egestas facilisis. Maecenas arcu risus, euismod ac lacus ac, euismod dictum nunc. Aenean non felis aliquet mi tincidunt bibendum. Curabitur ultricies ullamcorper gravida. In pretium nibh non eleifend egestas. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Proin auctor lacus erat, sit amet vestibulum lorem mattis in. Aenean dapibus at risus ac lacinia. Vivamus fringilla nulla diam, vel facilisis magna mollis maximus. Sed quis dolor tempor magna pharetra scelerisque. Nam velit felis, mollis sit amet risus et, imperdiet interdum nibh.</p>
</article>
<footer>Footer should be 450px wide and appear to the right of everything else.</footer>
<!-- Google CDN jQuery with fallback to local -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<!-- custom scrollbar plugin -->
<script src="../jquery.mCustomScrollbar.concat.min.js"></script>
<script>
(function ($) {
$(window).load(function () {
$.mCustomScrollbar.defaults.theme = "light-2"; //set "light-2" as the default theme
$("article").mCustomScrollbar({
axis: "x",
advanced: {autoExpandHorizontalScroll: true}
});
jQuery('article').css({'max-width': jQuery(window).width() - 581});
});
})(jQuery);
</script>
</body>

WordPress: Make sidebar match height of main content area

I'm taking an old WordPress site I designed years ago and now I'm making it responsive. Problem is I have a main content area on the site and a sidebar div and the issue is the sidebar div is not expanding down the entire height of the #contentWrap div on this site. I've already tried adding 100% heights to the #page, #contentWrap and #sidebar, all to no avail. On the old site design, I did a trick using background images, but that realistically won't work with a responsive desig.Any idea how I can make this work?
Site in question: http://destinationbeershow.com/episode-guide/
Code:
<div id="contentWrap">
<div id="content" class="narrowcolumn">
</div>
<div id="sidebar">
</div>
</div>
CSS:
#contentWrap {
width: 856px;
height: 100%;
}
#page {
background-color: #ac4f23;
text-align: left;
margin: 0px auto;
width: 856px;
height: 100%;
}
.narrowcolumn {
background-color: #ac4f23;
float: left;
padding: 0;
margin: 0;
width: 640px;
color: #FFF;
}
#sidebar {
padding: 16px 8px 10px 8px;
float: right;
width: 160px;
height: 100%;
font: 11px 'Lucida Grande', Verdana, Arial, Sans-Serif;
border-left: 10px solid #fff;
background-color: #ebd299;
}
You can make everything collapse below your 856px hard width and use percentages inside that, or you can fiddle with the math. You also don't mention how you are doing your media queries, I'm assuming mobile first, which means that IE8 won't see the columns unless you learn more about that or use desktop first responsive design, however to make the columns the same height no matter what is inside either, here's one way (display:table/display:table-cell) which stacks below the 856px width you have on your #page. Use percentages.
DEMO: http://jsbin.com/biyito/1/
CSS:
.narrowcolumn {
background-color: #ac4f23;
color: #fff;
box-sizing: border-box;
padding: 10px 20px;
}
#sidebar {
padding: 10px 20px;
border-top: 10px solid #fff;
background-color: #ebd299;
box-sizing: border-box;
}
#media (min-width:856px) {
#contentWrap {
width: 100%;
display: table;
}
.narrowcolumn {
width: 80%;
display: table-cell;
}
#sidebar {
display: table-cell;
padding: 10px;
width: 20%;
border-left: 10px solid #fff;
border-top: 0px;
}
}
HTML
<div id="contentWrap">
<div id="content" class="narrowcolumn">
<h1>HTML Ipsum Presents</h1>
<p><strong>Pellentesque habitant morbi tristique</strong> senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. <em>Aenean ultricies mi vitae est.</em> Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, <code>commodo vitae</code>, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis.</p>
</div>
<div id="sidebar">
<p><strong>Pellentesque habitant morbi tristique</strong> senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. <em>Aenean ultricies mi vitae est.</em> Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, <code>commodo vitae</code>, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis.</p>
</div>
</div>
the #contentWrap has no height... i tried I really tried to make it responsive with your content but it just doesn't work. For now if you define the height of it, the bar will be end to end.
In that page the height would be 1361px
If you can place the content in http://jsfiddle.net/ is much more easy to find and get to the problem.

absolute positioning and scrollable DIV

I have this tricky CSS problem: I have this HTML:
<div id="wrapper">
<div class="left"></div>
<div id="scroll">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque faucibus volutpat turpis at iaculis. Proin at nisl leo. Morbi nec blandit leo? Pellentesque interdum nunc sed nisl rhoncus gravida. Nunc sollicitudin, mi sit amet porta mollis, metus erat ornare odio, eu accumsan mauris diam nec augue. Ut tincidunt dui at lorem consequat vitae consectetur sapien pharetra. Suspendisse potenti. Donec turpis enim, varius accumsan congue vitae, rhoncus ut justo. Curabitur tristique lobortis eros ut pharetra. Maecenas non condimentum justo. Integer tincidunt; velit quis auctor varius, magna lorem pharetra urna, eget pellentesque leo nibh at mi. Ut pretium bibendum dui vel venenatis. Proin vel sem vitae lacus tincidunt bibendum. Pellentesque blandit mauris sit amet mauris sollicitudin pretium. In molestie condimentum nisi placerat consequat.
</div>
<div class="right"></div>
</div>
With this CSS:
#wrapper {
position: relative;
display: block;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
height: 47px;
}
#scroll {
position: relative;
height: 100%;
width: 10000px;
}
div.left, div.right {
position: absolute;
display: block;
background-color: rgba(255, 0, 0, 0.5);
width: 24px;
height: 100%;
z-index: 100;
top: 0;
}
div.left {
left: 0;
}
div.right {
right: 0;
}
And the visual result is this:
For some reason, the div.right is moving when I scroll the #scroll. I want it to always float at the boundary of #wrapper.
This is what I get right now:
Here is the jsfiddle: http://jsfiddle.net/b5fYH/
Thank you
Edit
Just because it wasn't obvious, it must work on mobile devices.
You have to know the difference between position: absolute and position: fixed.
The first one means: place the element in absolute position within relative element and keep in in that place (relatively).
The second: place the element in absolute position within window (frame) and keep it there no matter what happens.
Check this fiddle: http://jsfiddle.net/b5fYH/1/
The problem is with how overflow-x changes the wrapper div width.
The solution I found was:
Demo: http://jsfiddle.net/5jWpG/
wrapping the whole thing with a new div with the id wrapper-container
then adding the following CSS code:
#wrapper-container {
position: relative;
}
#wrapper {
position: static; /* or remove position relative from your code */
}
div.left, div.right {
bottom: 16px;
height: auto; /* or remove height: 100% from your code */
}

Resources