I'm developing a control aiming to display activity blocks on a calendar grid. It is a plain JavaScript/CSS, relying on jQuery for DOM manipulation and such. Here is a picture:
There are bands A and B, each containing a couple of activity blocks ([1,2], [3,4]). Activities can either overlap or follow each other sequentially. My goal is to place the activity blocks accordingly: if activities overlap like [1,2], I want them wrap and sit on top of one another like pictured; if they are sequential like [3,4], I want them side by side, NOT like pictured.
Additionally, I would like bands' (A,B) height to adjust automatically. Thus, a band with overlapped activity blocks would have twice the height of the band with sequential ones.
At this point I can get either one or the other.
If activity blocks have display: block;
, the activities wrap regardless whether they actually overlap (3,4). Band's height does get adjusted accordingly.
If activity blocks have display: inline-block;
, activities share the same height so one gets hidden by the other (1,2). The band stays one activity block in height.
Everything is a div
and here is the relevant HTML/CSS:
<div class="band">
<div class="activity-block" style="left: 331.429px; width: 11.4286px;"></div>
<div class="activity-block" style="left: 160px; width: 297.143px;"></div>
</div>
<div class="band">
<div class="activity-block" style="left: 205.714px; width: 22.8571px;"></div>
<div class="activity-block" style="left: 365.714px; width: 3417.14px;"></div>
</div>
<div class="band"></div>
Bands (A, B):
.band {
min-height: 20px;
}
Activity blocks (1,2,3,4):
.activity-block {
background-color: #66C6C2;
border-radius: 3px;
display: block;
height: 20px;
margin-bottom: 5px;
margin-top: 5px;
position: relative;
}
left
and width
of an activity block are set from JavaScript.
I would like to get there using only two CSS classes, one for the band and one for the activity blocks. I realize the goal can be achieved using JavaScript, but I wonder if this is something possible via CSS only.
As commenting users suggested there is no way to do this in CSS only. CSS works in let's call it "rows". What you are trying to achieve is to based on some condition place content in one or two rows, that is something that CSS cannot handle. You can only specify how content behaves in its own row. The closest you can get is to define elements as inline-block with proper left padding when not overlapping and block when they are, but you cannot do that without using JavaScript for handling the logic.
See if it suits your demands: you want to set positions in javascript and let css break lines for you if there is an overlap, right?
The idea is to put each block to float to one side and set the margins with your javascript code. But the band div must be float, or else it won't grow to accomodate the line break that happens in case of overlap (more on this in Floating elements within a div, floats outside of div. Why?).
<html>
<head>
<style>
.activity-block {
background-color: #66C6C2;
border-radius: 3px;
height: 20px;
margin-bottom: 5px;
margin-top: 5px;
}
.band {
min-height: 30px;
border: solid 1px;
width: 1200px;
float: left;
}
.fl {
float: left;
}
.fr {
float: right;
}
</style>
</head>
<body>
<div class="band">
<div class="activity-block fl" style="margin-left: 331px; width: 81px;">1</div>
<div class="activity-block fr" style="margin-right: 160px; width: 497px;" id="x2">2</div>
</div>
<div class="band">
<div class="activity-block fl" style="margin-left: 205px; width: 22px;">3</div>
<div class="activity-block fr" style="margin-right: 365px; width: 417px;" id="x4">4</div>
</div>
</body>
I made a jsFiddle for testing:
https://jsfiddle.net/vdusch4y/6/
Some restrictions you need to check:
In the jsFiddle example, try changing the band width, or block margins/widths, to see how the break occurs automatically, leaving the band with a bigger height.
Hope it helps!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With