Reputation: 14747
I am creating a calendar where all the events are displayed in a single div. According to the top
and height
values, the event should be placed in a determinate place. Let me show you.
In this image, both events at 6am are at the same vertical alignment. I can solve that behavior using float: left
(jsfiddle).
If events do not have vertical alignment
conflics (the height and top don't collide) then I can emulate this behavior using absolute position
(jsfiddle) but NOT float
.
The real problem comes when I try to place the events at 9am and 9:40am and make them look like the image above. Asume the following properties:
9:00
height: 50px, top: 200px9:40
height: 50px, top: 230px9:00 event
: 200px + 50px = 250px9:30 event
: 230px20px
(250px - 230px) vertically.That is why I tried to do something like this:
<div class="container">
<div class="event" style="height: 50px; top: 200px; float:left;">9 AM</div>
<div class="event" style="height: 50px; top: 230px; float:left;">9:40 AM</div>
</div>
...but float property does not work in elements with absolute position.
My idea is to treat the top
value as a guide to place the event vertically in the calendar according to its hour. For example,
I tried to solve this by myself using pure ccs, but I do not mind apply javascript. However, I can not show you my attempts with javascript because I do not even can make a considerable css result. As I said before, I am using top property because I thought it could be easy position manipulation, but I could use another method if is necessary. Thank you in advance.
Upvotes: 1
Views: 987
Reputation: 35670
Using relative positioning almost solves your issue. However, it leaves gaps between events:
The only way I know to solve this problem is using absolute positioning, with JavaScript determining top
and left
coordinates:
var events= [].slice.call(document.querySelectorAll('.container div')),
//array of event elements. See http://davidwalsh.name/nodelist-array
count= [], //running total of events during an hour. used to calculate left offset.
i, //loop through the events
time, //event time as array, such as ['6','AM']
hour, //event hour (1 - 24)
minute, //event minute (0 - 59)
offset; //top offset based on hour and minute
events.sort(function(a,b) {
return a.textContent < b.textContent ? -1 : 1;
});
for(i = 0 ; i < events.length ; i++) {
time= events[i].textContent.split(' ');
hour= time[0].split(':')[0] * 1;
if(time[1]==='PM' && hour !== 12) {
hour+= 12;
}
minute= time[0].split(':')[1] || 0;
offset= hour+minute/60;
count[hour]= (count[hour] || 0)+1;
events[i].style.top= (offset-6)*50 + 'px';
events[i].style.left= count[hour]*100-100 + 'px';
}
Note that this code needs some tweaking to avoid events covering up other events, as you'll in the Fiddle for 12:00 PM.
Upvotes: 3
Reputation: 891
What if you use margin-top
instead of top
, does it work for you? You might be able to get this result:
You might also need to create a container div
for every hour and include the underlying event divs in there:
<div class="container">
<div class="event" style="height: 50px;">6AM</div>
<div class="event" style=" height: 50px;">6AM</div>
</div>
<div class="container">
<div class="event" style="height: 50px;">9 AM</div>
<div class="event" style="height: 50px; margin-top: 25px;">9:30 AM</div>
<div class="event" style="height: 50px; margin-top: 33px;">9:40 AM</div>
</div>
Here is some sample code on JSFiddle for reference.
Upvotes: 0
Reputation: 92440
You should add positioning to your divs. If you add position:relative
to your classes you will be able to use top:xxpx
to offset the vertical position. I think you will need to think about a lot of edge cases that might make a pure css solution difficult, but thought this might at least help.
Here's a fiddle: http://jsfiddle.net/markm/qvevedva/
Upvotes: 3