So in short, you cannot do what you want with a pure css3 at the time of writing. The target API you desire is the CSS3 Multiple Columns. If you look through the examples within the spec you will see it was not written with the use case of mixing balanced and non-balanced (sequential) column-filling at the same time on a given element.
The spec was written to achieve either techniques at different times, thus similar (but ultimately slightly different) functionality to your request. However, we can achieve your target functionality though, with a little help from javascript! Explanation and code below Tested on Chrome 38 and FF 33 IE 11.
If you are feeling up to learning something knew, check out mutationobserver which potentially mitigates your concerns in comments (of unaware devs changing contents on the fly). It allows us to track dom changes and set classes appropriately. my first attempt worked, but not cross browser, see edit revision before the rollback.
I'm going to refer to your three requirements as states.
Overview
- States 1 and States 2 share the same css (
column-fill:auto
).
- State 3 because of the multiple columns spec requires different css rules(
column-fill:balance
).
- The rules for state 3 are only required for desired functionality when states 1 and states 2 cannot contain all the text (i.e. overflow).
- With some help from javascript we can apply the class changes for state 3 when there is overflow in states 1 and 2.
- In reverse, if content is removed, on a change we can reapply the class for states 1 and 2
- The css attribute
column-count
is the number of columns to span the given parent element. In your case, we want 2.
To achieve state 1 and state 2
Whenever you set the height of the column elements, the browser will render more columns outward when there is not enough room. The column widths are at the width of the target span. So setting the height is necessary to have the column fill sequentially (as you requested, "like column-fill:auto
"). See snippet below for code, the css rules for "origState
" apply to states 1 and 2.
To achieve state 3
However this state gives us a problem. Overflow when the height of the columns is set produces more columns of the same width as the original columns. Now you want it to behave like column-fill:balance
with an unlimited height, that is scroll-able. This is not attainable within the css3 multiple column spec when you want to be using sequential filling (i.e. column-fill:auto
). However, when no height is set within the columns and the height is set within the parent (with proper scrolling css values) we can achieve what you want. See snippet below for code, the css rules for "overFlowState
" apply to state 3 notice the height was removed.
Full Solution
Now we have to bring the two target functionality requests together. You have to determine when to apply the second class to a child container, this can be done by checking for overflows on states 1 and 2. You can do this check once the element has been added to the dom/domready. (Was going to write myself, but borrowed the javascript function for checking overflows from this post). Please see code snippet for javascript.
function isOverflowed(element){
return element.scrollHeight > element.clientHeight || element.scrollWidth > element.clientWidth;
}
var elements = document.getElementsByClassName("origState");
for(var i = 0; i < elements.length; i++){
var element = elements[i];
if(isOverflowed(element)){
element.className = "overFlowState";
i--;
}
}
.parent{
overflow-x:hidden;
overflow-y:auto;
width:100%;
height:7em;
}
.origState{
-webkit-column-count:2;
-moz-column-count:2;
column-count:2;
-moz-column-fill:auto;
height:inherit;
}
.overFlowState{
-webkit-column-count:2;
-moz-column-count:2;
column-count:2;
}
<div class="parent">
<div class="origState">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
</div>
</div>
<div class="parent">
<div class="origState">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat
</div>
</div>
<div class="parent">
<div class="origState">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem. Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius.
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem. Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius.
</div>
</div>
Conclusion
The issue at hand is that overflow of the contents of columns are supposed to generate more columns, when there is a height set. We can obtain the scrolling region with the parent as expected by removing the column height in the css. We can bring the two together by swapping classnames with a little help from javascript.