Css column-count should respect only first child - css

I'm trying to use the column-count to make a kind of week calendar to user tasks.
The main div of the week has the property of column-count to 7 and ALWAYS there will 7 childs. The seven days of this week.
Inside this days there are the tasks, but the number of tasks is variable and it break the column-count logic.
Why column-count not consider just the first childs inside it?
Here's an example of what I'm saying: https://jsfiddle.net/nby5ctb2/
On the second list, I wanted the tasks 1, 1.1 and 1.2 on top of each other, and when there are no childs just skip these day.
The css I used was just this:
.week {
-moz-column-count: 7;
-webkit-column-count: 7;
column-count: 7;
}
Thanks advanced

You seem to have misunderstood the purpose of column-count and are therefore misusing it.
It's purpose is to take some content and divide it into the given number of columns with as close to equal amounts of content as possible. The only tool you have is break-inside:avoid to keep "block-like" content together.
But if you do use it to make one column taller than the rest, your are making all columns the same height, because that's what CSS columns does. So, for example, using break-inside:avoid on .day. will cause other shorter .days to pile up in the same column. It would only work if days in your week had equal amounts of content, which is clearly not the case.
First question that comes in mind is: why not use flex? Since you probably want your day's widths equal, you need to add width to the children. By default display:flex children have flex: 0 1 auto, which makes them flexible, depending on contents.
.week {
display: flex;
}
.week > * {
width: calc(100% / 7)
}
Fiddle.

CSS Column is not the best solution to accomplish that. It strives to flow the content column wise, from left to right, and what you ask is to fight against it.
I recommend you use i.e. Flexbox, which does that very simple, and with better browser support.
.week {
display: flex;
flex-wrap: wrap;
}
.week .day {
flex-basis: calc(100% / 7);
word-break: break-all;
overflow: hidden;
}
This works
<div class='week'>
<div class="day">
<div class="task" >Task 1</div>
</div>
<div class="day">
<div class="task" >Task 2</div>
</div>
<div class="day">
<div class="task" >Task 3</div>
</div>
<div class="day">
<div class="task" >Task 4</div>
</div>
<div class="day">
<div class="task" >Task 5</div>
</div>
<div class="day">
<div class="task" >Task 6</div>
</div>
<div class="day">
<div class="task" >Task 7</div>
</div>
</div>
<br />
<br />
This <strike>doesn't</strike> work too, now
<div class='week'>
<div class="day">
<div class="task" >Task 1</div>
<div class="task" >Task 1.1</div>
<div class="task" >Task 1.2</div>
</div>
<div class="day">
<div class="task" >Task 2</div>
</div>
<div class="day">
</div>
<div class="day">
</div>
<div class="day">
<div class="task" >Task 5</div>
<div class="task" >Task 5.1</div>
</div>
<div class="day">
</div>
<div class="day">
</div>
</div>

Related

Third element ends up in new line in Safari

I have a simple Bootstrap layout:
<div class="row">
<div class="footer_column col-md-4">
<div class="footer_item">
ABOUT
</div>
<div class="footer_item">
Contact Us
</div>
<div class="footer_item">
Terms & Conditions
</div>
<div class="footer_item">
Privacy Policy
</div>
</div>
<div class="footer_column col-md-4">
<div class="footer_item">
SITE RESOURCES
</div>
<div class="footer_item">
General Rules
</div>
<div class="footer_item">
Scoring
</div>
<div class="footer_item">
Game Coins
</div>
<div class="footer_item">
<a class="store-show">Store</a>
</div>
<div class="footer_item">
Account Types
</div>
</div>
<div class="footer_column col-md-4">
<div class="footer_item">
MORE FANTASY FOOTBALL
</div>
<div class="footer_item">
<div class="footer_item">
Fantasy Game
</div>
</div>
</div>
</div>
In Chrome and Firefox it looks like it's supposed to (a 3 column layout):
But in Safari the 3rd column ends up in a new line below the other. When I inspect it, it has the correct width (exactly 1/3 of the total row width) in both Chrome and Safari.
I am seeing this when I inspect the element:
.col-md-4 {
flex: 0 0 33.3333333333%;
max-width: 33.3333333333%;
}
When I remove the max-width attribute, each column spreads out to 100%. This is expected I suppose. But when I add width: 20% for example, the width of each column remains the same as it was!
How can I make Safari behave?
If you're using a container around the row then add a helper class to remove the before content.
<div class="container before-fix"><!-- content --></div>
.before-fix::before {
content: none;
}
I fixed this here. The problem was the flex was overriding the default width.
This is what the CSS is now:
.col-md-4 {
flex: none;
max-width: 33.3333333333%;
width: 20%;
}
It successfully sets the width of the columns to 20% instead of 33.3%.
Here's a really clean way using grid instead of bootstrap...
.three-columns {
display: grid;
grid-template: 1fr 1fr 1fr;
}
<div class="three-columns">
<div>column 1</div>
<div>column 2</div>
<div>column 3</div>
</div>

Order and stack 3 columns with bootstrap 4

I have this structure in bootstrap columns:
And I want you to change to a lower resolution, be ordered as follows:
I found how to do it with flexbox here:
Flexbox: reorder and stack columns
But I can not change the entire structure of my project to flexbox, so I want to know if with bootstrap 4, it is possible to do so.
Thank you very much.
My poor test.
#import url( 'https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css' );
div {
text-align: center;
height: 60px;
}
#left {
background: yellow;
}
#middle {
background: blue;
}
#right {
background: coral;
}
<div class="container">
<div class="row">
<div class="col-sm-3 col-md-3">
<div id="left">COLUMN 1</div>
</div>
<div class="col-sm-6 col-md-6">
<div id="middle">COLUMN 2</div>
</div>
<div class="col-sm-3 col-md-3">
<div id="right">COLUMN 3</div>
</div>
</div>
</div>
You can use the Bootstrap 4 (alpha 6) utility classes to avoid the extra CSS. 1-2-3 becomes 3-2-1 on mobile.
<div class="container">
<div class="row">
<div class="col-sm-8 col-md-6 push-md-3">
<div id="middle">COLUMN 2</div>
</div>
<div class="col-sm-4 col-md-6">
<div class="row">
<div class="col-md-6 pull-md-12 flex-last flex-md-unordered">
<div id="left">COLUMN 1</div>
</div>
<div class="col-md-6">
<div id="right">COLUMN 3</div>
</div>
</div>
</div>
</div>
</div>
http://codeply.com/go/GIcPuzURbs
I assume by "resolution" you mean smaller screen size?
Here's a possible solution that uses some bootstrap push/pull grid utilities to reorder the columns in a medium size viewport, and then rearrange the layout in small size viewport the way you've shown in your diagram. In the small screen view, within a media query I use the css property order to reorder the 1 and 3 columns vertically Hope it gets you on the right track
<div class="container">
<div class="row">
<div class="col-sm-8 col-md-6 push-md-3">
<div id="middle">COLUMN 2</div>
</div>
<div class="col-sm-4 col-md-6">
<div class='row'>
<div id='leftcont' class="col-md-6 pull-md-12">
<div id="left">COLUMN 1</div>
</div>
<div id='rightcont' class="col-md-6">
<div id="right">COLUMN 3</div>
</div>
</div>
</div>
</div>
</div>
CSS:
div {
text-align:center;
height:60px;
}
#left{background:yellow;}
#middle {background:blue;}
#right {background:coral;}
#media (max-width: 768px) {
#leftcont { order: 2; }
#rightcont {
order: 1;
margin-bottom: 1em; }
}
New fiddle
The height of the divs might have to be adjusted for grid breakpoints but since the colored divs were only for a test, i didn't match those to your example
have you tried to pull column 2 for lower resolution?

Bootstrap grid displays columns as rows

I have bootstrap grid
<div class="container">
<div class="row">
<div class="col-sm-1">Column 1</div>
<div class="col-sm-2">Column 2</div>
<div class="col-sm-1">Column 3</div>
</div>
<div ng-repeat="Item in Items">
<div class="row">
<div class="col-sm-2">{{Item.Field1}</div>
<div class="col-sm-4">{{Item.Field2}}</div>
<div class="col-sm-6">{{Item.Field3}}</div>
</div>
</div>
</div>
It should display a 3-column grid, instead the columns are displayed as rows. What am I doing wrong?
So your first row is the like the "header" and the next row are the records. Your header is 1-2-1 but your records are 2-4-6 => it won't line up. To keep it from stacking even on small screens you can do col-xs-x instead.
<div class="row">
<div class="col-xs-3">Column 1</div>
<div class="col-xs-6">Column 2</div>
<div class="col-xs-3">Column 3</div>
</div>
<div ng-repeat="Item in Items">
<div class="row">
<div class="col-xs-3">{{Item.Field1}</div>
<div class="col-xs-6">{{Item.Field2}}</div>
<div class="col-xs-3">{{Item.Field3}}</div>
</div>
</div>
I'm assuming you want them to always line up. Bet way to do that will be this:
<div class="container">
<div class="row">
<div class="col-sm-2">Column 1<br>
{{Item.Field1}}
</div>
<div class="col-sm-2">Column 2<br>
{{Item.Field2}}</div>
<div class="col-sm-2">Column 3<br>
{{Item.Field3}}</div>
</div>
</div>
Alternatively, you can replace the br and wrap the elements in divs and display: block;
Working example here:
http://www.bootply.com/tb10AKqzM1
Having put in the code myself, it actually does work. It will put in rows when the viewport size is below the small viewing size (so xs, extra small size). If you want to view it on all viewing sizes then you would have to add xs instead of s to all your classes.

display: table-row with multiple layers of rows before table-cell

This is the HTML that I am working within. (PLEASE NOTE: I cannot change the HTML, only the styling).
<div class="table">
<div class="table-row">
<div class="table-row-1">
<div class="table-row-2">
<div class="table-col">Column 1</div>
<div class="table-col">Column 2</div>
</div>
</div>
<div class="table-row-1">
<div class="table-row-2">
<div class="table-col">Column 1</div>
<div class="table-col">Column 2</div>
</div>
</div>
</div>
<div class="table-row">
<div class="table-row-1a">
<div class="table-row-2">
<div class="table-col">Column 1</div>
<div class="table-col">Column 2</div>
</div>
</div>
<div class="table-row-1b">
<div class="table-row-2">
<div class="table-col">Column 1</div>
<div class="table-col">Column 2</div>
</div>
</div>
</div>
</div>
As you can see, there are multiple rows containing the actual cells. I am applying display:table to the main div, display:table-row to the first parent row, and then display:table-cell to the column cells.
I am unable to use an actual table as I cannot change the HTML.
I am unsure what to apply to the extra row containers to ensure that they aren't affecting the structure of the table.
This code is being used to make a flexbox grid which is more structured on larger screens, meaning that the cells within the same column are the same width. If you could suggest another solution other than the table displays, please do, but I have been unable to find another option.
I am working with less.

Dynamic columns/rows

Wondering--does anyone know of any good articles explaining the CSS technique allowing multiple instances of a class to flow down the page relative to the items above it. Not explaining it that well.
Veerle' Pierter's does it on this page: http://veerle.duoh.com/belgiangraphicdesign Although I'm not sure I want to use a technique like her's that requires entering of the height per element via her EE installation.
I made a little graphic of what I am trying to acheive;
The key is I need a robust technique for doing it. Something where the markup could be as simple as;
<div class="box">
Number 1
</div>
<div class="box">
Number 2
</div>
<div class="box">
Number 3
</div>
<div class="box">
Number 4
</div>
<div class="box">
Number 5
</div>
...
Would love any pointers in the right direction.
As the others have pointed out, using only CSS you could group the boxes into columns. Unfortunately this will not look good if your content is dynamic and you don't know the heights of all the boxes (your columns could end up drastically different lengths). If you want to calculate the heights of boxes in order to arrange them nicely, you are going to have to use Javascript. There's certainly nothing wrong with using Javascript - it's the right tool for this job!
As for the implementation, the logic would go something like this: start by adding the first 4 boxes, one at the top of each column. Then keep track of the total height of each column using Javascript's clientHeight property, and for each new box you want to add; simply append it to the end of the shortest column with appendChild().
If you decide to go with jQuery, I can recommend a plugin called jQuery Masonry.
She isn't setting a height for those boxes.
Jquery is dynamically positioning each box and as far as I know that's the only way to achieve that effect with the markup you describe in your post.
If you don't want to use a javascript solution the only way to do it is to have wrapper columns, but that would change your markup dramatically.
<div class="container">
<div class="box">number 1</div>
<div class="box">number 2</div>
<div class="box">number 3</div>
</div>
<div class="container">
<div class="box">number 4</div>
<div class="box">number 5</div>
<div class="box">number 6</div>
</div>
<div class="container">
<div class="box">number 7</div>
<div class="box">number 8</div>
<div class="box">number 9</div>
</div>
She achieves it positioning the boxes absolutely.
But you can achieve it with very simple css, assuming you can control the order by which the items appear.
You have to group them in columns (and not in rows as is usual), but it works like a charm.
Use HTML like this:
<span class="column">
<div class="box">number 1<br />with two lines</div>
<div class="box">number 4</div>
<div class="box">number 7<br />with two lines</div>
</span>
<span class="column">
<div class="box">number 2</div>
<div class="box">number 5<br />with two lines<br />or even three<br />or four!</div>
<div class="box">number 8</div>
</span>
<span class="column">
<div class="box">number 3</div>
<div class="box">number 6</div>
<div class="box">number 9</div>
</span>
And CSS like this:
.column {
clear: left;
width: 25%;
display: inline-block;
vertical-align: top;
}
.box {
border: solid 1px blue;
}
Test it on JSFiddle.net.
Use span for the columns, because IE7 does not accept display: inline-block; for elements that are naturally block elements. (Meh.)

Resources