tags:

views:

49

answers:

3

I have a page filled with many fixed-size boxes in a grid layout (div's simply piled up with float:left). On hovering the mouse on any of them, a 'popup' - larger div with the same and also additional info is shown over it, as if the box expanded in all directions (but not moving the other boxes, it's shown also over them). Simplified html/css below. It's like thumbnails/full images, but the actual content is a pile of various html data, including links, etc.

The problem is that in this way the 'popup' div for the leftmost/rightmost boxes goes over the screen, triggering the scrollbar; or they are cut off if I don't allow the overflow.

I would like instead to reposition these popups to left/right so that they stay within the total borders. How to approach this need?

I can't do this server-side as the server does not know which boxes will be rightmost/leftmost - it depends on window size, how many columns will fit there. My first idea is to use javascript to change the positioning for all the popups right after the page is loaded, but I don't know how to a) find out which popups would be sticking out of the frame; and even b) find out the size of the popups, since they are hidden normally, which means width=height=0 until they are shown.

Perhaps a completely different approach of showing these popups would be easier than repositioning the div's that I currently have?

Currently Prototype/scriptaculous is used at some other pages, the server side is ruby on rails.

<div class="frame">
  <div class="box", id="object123" >
    small, fixed size content here
    <div class="popup">
      large, variable size/width/height content here that describes object123
    </div>
  </div>
  <div class="box", id="object456" >
    small, fixed size content here
    <div class="popup">
      large, variable size/width/height content here that describes object456
    </div>
  </div>
  ... many other similar boxes.
</div>

div.frame {
  overflow: hidden;
}
div.box {
  border:1px solid #efe9dc;  
  margin:5px;
  position:relative;
  float:left;
  height:70px;
  width:150px; 
}
div.popup {
  min-width:200px;
  display:none;
  position:absolute;
  left:-30px;
  top:-30px;    
  z-index:1000;
}
div.box:hover .popup { display: block; }
A: 

As my understanding you have multiple small divs which ave the thumbnails and you have a div to sow large content for each image. So for each image there are two divs.

Tats why you are having difficulty for each div.some will be left , some center , some on right.

Instead of that , use a common div to show large content for all the smaller div. Pass a parameter on hover and show the content in that div using server side code.

That means your style is fine , you just position only one div in center by using

left:100px top:100px

you modify it as you want. Put large content in that single div for all smaller divs

Use Firefox Firebug for better understanding of position

zod
Your proposal would mean that the popup is always displayed in center of screen instead of over the specific box, which is the intent. In this way would be impossible to click on any links in the popup, since by simply moving the mouse to the middle of screen you'd likely hover over some other boxes and get different popup already.The desired layout would be that for all 'middle' boxes the popup is spread out to all directions equally from the original, smaller boxes; for right-side boxes the popup is right-aligned against the border, for left-side boxes the popup is left-aligned.
Peteris
Ok !.Then i dont see any other way than using seperate style for left,middle and right. Or based on parameters apply different style by addclass ,removeclass or addcss. These are the names from jquery, prototype may be different
zod
A: 

right now your div.popup is positioned absolute to div.box; if you removed the position from div.box and put it on div.frame, the popups would be absolute to the frame. you can then set left/top/right/bottom to be offset from the frame's edges instead.

i hope this helped :)

Alex Rosario
well, in that case the offset from frame edges would need to be somehow computed to put the popup over the original box, and that can't be done with CSS as far as I know, so time for javascript.
Peteris
A: 

In the end this is what I did.

I replaced the popups with css+jquery script that expands the content box larger/above the normal grid; centers the 'popup' over the place of the original box, and if it goes over the sides, then adjusts the position. As a bonus, the functionality works on everything that I tag with the 'expands' 'expand_show' 'expand_hide' classes, so no duplication as it is applied in several places.

sample html

<div class="box_grid expands">
    <div class="box_content">
       basic content that's always visible
       <p class="expand_hide>short content summary shown in the small boxes</p>
       <p class="expand_show> detailed content</p>
       <div class="expand_show> detailed extra content</div>
    </div>
</div>

css and javascript to show it

div.box_grid {
  margin:5px;
  float:left;
  height:80px;
  width:170px;
}
div.expanded { position:relative; }
div.expanded > * { 
  position:absolute;
  width:auto;
  height:auto;
  z-index:1000;
  min-width:100%;
  min-height:100%;  
}
div.expands .expand_show { display:none; }
div.expanded .expand_show { display: block; }
div.expanded .expand_hide { display: none; }

$(document).ready(function(){
      $('.expands').hover(
        function(){ 
          grid = $(this);
          expanded = grid.children();
          border = $('.content_borders');

          grid.addClass('expanded');          
          var top = (grid.outerHeight() - expanded.outerHeight())/2;
          var left = (grid.outerWidth() - expanded.outerWidth())/2;            

          var left_limit = border.offset().left + 5 - grid.offset().left;
          var right_limit = border.offset().left + border.outerWidth() - expanded.outerWidth() - 5 - grid.offset().left;
          var bottom_limit = border.offset().top + border.outerHeight() - expanded.outerHeight() - 5 - grid.offset().top;

          if (left < left_limit) { left = left_limit }
          if (left > right_limit) { left = right_limit }
          if (top > bottom_limit) { top = bottom_limit }

          expanded.css('top',top);
          expanded.css('left',left);
        },
        function(){ $(this).removeClass('expanded') }          
      );
    });
Peteris