2

I have a piece of CSS implementing a click suckerfish menu.

The markup:

<table>
<tr>
<td>
<div class="bodywrapper">
<a class="button" href="#">
   <ul class="menu">
      <li>test test test</li>
      <li>test test test test test test test test test test test test test test test</li>
   </ul>
</a>
</div>
</td>
</tr>
</table>

Styles:

td{
   width: 80px;
}

.button{
  position: relative;
  display: inline-block;
  background-color: red;
  width: 10px;
  height: 27px;

}

.button:focus .menu, .button:active .menu{
  display: block;
}

.menu{
  display: none;
  position: absolute;
  min-width: 99px;
  max-width: 700px;
  width: auto;
  border: 1px black solid;
  margin-top: 27px;
}

Update, the above is actually contained within a table cell of fixed with

And a fiddle: http://jsfiddle.net/dAAXp/3/

The problem: I want this style definition to be used across the whole application. Therefore, the length of the text in the <li> will vary. However, the behaviour I want is that the menu has a minimum and maxmium width. I have set this using min-width and max-width for .menu. But for some reason, even if the content in the <li> is less than the max-width, the width of the menu is constrainted to the min-width.

Could someone tell me why this is happening?

F21
  • 32,163
  • 26
  • 99
  • 170

1 Answers1

4

EDIT: See bottom for answer to change in question (the solution is exactly the same)

The reason is that the A is the first positionable (relative) block that the UL can expand into. Because the anchor is constrained to 10px the contained UL can only fill according to that anchors box dimensions.

What you need to do is remove the position:relative from the anchor, add another 'invisible' container and set its position relative then your UL can expand upto the size limit of that element. see this fiddle for a fixed version

In 'english' this is what your css says:

UL: Ooh okay so my width is 100% (as you have not set width) of first parent marked with relative... Right so the Anchor above me is marked relative so my 100% width is 10px... but wait my min-width is 99px so I shall honour that.

UPDATE:

See fiddle with wrapper moved outside the table

The logic is exactly the same as in first - you could probably set position relative on the table as it's container AS LONG AS its width is 100% or greater than your required min/max widths of the contained child.

On a side note once you get to the point where you cannot have a parent width bigger than required you will have to start looking at absolute positioning and breaking the element out of the parent (but i'll leave that for now)

FOR THE SEMANTIC AMONG YOU:

I have added div wrapper - you can easilty apply this behaviour to any parent (i.e. the table/tr/td as long as it is wider than you need the min-max width @phpdev but once again if you reach the point where you parent is just not wide enough then you may have to break semantics

Paul Sullivan
  • 2,865
  • 2
  • 19
  • 25
  • I find it strange that this works, because your "the contained UL can only fill according to that anchors box dimensions." is not correct. In the OP's example, the UL was already 99 px wide. But anyway, it does work, so +1. – Mr Lister Apr 15 '12 at 07:02
  • see my 'english' explanation @MrLister – Paul Sullivan Apr 15 '12 at 07:02
  • 1
    Thanks. I have the feeling I should be offended, but since it actually helped, I can't. ;) – Mr Lister Apr 15 '12 at 07:05
  • No offence meant @MrLister - I've coded for a very long time and I have to admit CSS is one of those 'with neither rhyme nor reason' languages/skills but once i understood the position/float/box model it made a load more sense but there are hundreds of gotchas – Paul Sullivan Apr 15 '12 at 07:08
  • Your solution works great! :) But, I need to put that in a table cell of fixed width and ran into the problem again. I have updated my question. Could you suggest how to deal with that? – F21 Apr 15 '12 at 08:36
  • added new fiddle @phpdev but the solution is exactly the same concept – Paul Sullivan Apr 15 '12 at 09:15
  • can you mark it as answer (if it does in fact work for you of course) @phpdev thanks – Paul Sullivan Apr 15 '12 at 15:18
  • Sorry, was out of office, so didn't have a chance to try. I just tried it and it seems to have worked quite well :) However, I am not usually a fan of 'wrappers' because they don't offer any semantic value. I will mark your answer as correct, but if any one can chime in with a solution that doesn't require any wrappers, that will be great :) – F21 Apr 15 '12 at 23:26
  • @phpdev happy to keep to semantics (see edit at bottom for 'semantics devotees'). In short you can avoid semantic breakages by careful use of relative (i.e. work out all the places where your DOM/design requires breaking away from the standard '100% width or less of parent' model and only where you run out of space use wrappers... IMHO you will never get rid of this unsemantic bloat due to complexities of layout but hey ho - minimisation is the key I think – Paul Sullivan Apr 16 '12 at 21:25
  • +1 ... Thanks for this, saved me all sorts of hassle with the twitter/bootstrap dropdowns :) – Richard Sep 14 '12 at 11:30