2009-12-07 12 views
11

Tengo un menú horizontal. El marcado se ve así:CSS: arreglado con menú horizontal, con pestañas de ancho variable, usando ul

<ul class="menu"> 
    <li>Item 1</li> 
    <li>Longer Item 2</li> 
    <li>Item 3</li> 
</ul> 

submenús y menús desplegables Suckerfish vendrán después.

El ul necesita abarcar el ancho de la página (por ejemplo, 100% o 1000 px).

La lis debe variar en anchura en función de su contenido.

Así, el resultado sería el siguiente aspecto:

-----------------100% of page------------ 
|--Item 1--|--Longer item 2--|--Item 3--| 

Ahora bien, es fácil de hacer esto mediante la fijación de un ancho para cada etiqueta li, sino porque el menú se CMS impulsado Me es posible el ancho de las pestañas para variar automáticamente. Con una tabla esto sería trivial, pero no puedo pensar en una manera de hacerlo con un ul.

Respuesta

4

aquí está mi solución jQuery:

var actualWidth = 1000; 
var totalLIWidth = 0; 

// Calculate total width of list items 
var lis = $('ul li'); 

lis.each(function(){ 
    totalLIWidth += $(this).width(); 
}); 

// Work out how much padding we need 
var requiredPadding = Math.round(((actualWidth-totalLIWidth)/lis.length)/2); 

// To account for rounding errors, the error is going to be forced into the first tab. 
var roundingErrorFix = (requiredPadding*lis.length*2)+totalLIWidth-actualWidth; 

// Apply padding to list items 
lis.each(function(i) { 
    if(i==0) { 
     $(this).css('padding-left',requiredPadding-roundingErrorFix+'px') 
      .css('padding-right',requiredPadding-roundingErrorFix+'px'); 
    } 
    else { 
     $(this).css('padding-left',requiredPadding+'px') 
      .css('padding-right',requiredPadding+'px'); 
    } 
}); 
+0

Buena solución, pero funcionó solo después de dividir 'roundingErrorFix' entre 2 antes de aplicarlo al primer elemento. –

+0

Gran respuesta: una cosa a tener en cuenta es que el ancho del elemento de la lista no incluye los bordes, así que agregue los bordes al totalLIWidth en la línea 10 (después del ciclo lis.each). –

-1

Si está tratando de darle estilo al ul (de modo que se extienda por toda la página), lo mejor es envolverlo en un div, y darle estilo al div, y luego permitir que el ul se estire tan lejos como su contenido lleva

30

este es un caso para

display: table-Man

ul { 
    display: table; 
    width: 100%; 
    table-layout: fixed; 
} 
li { 
    display: table-cell; 
} 

Desafortunadamente, usted debe abandonar la idea de apoyar IE 6 y 7, pero otra cosa es el camino a seguir (o cambiar a tablas HTML, que pueden estar o no muy alejadas del contenido semántico del marcado).

+2

+1 hilarante .... –

+0

Gracias - por supuesto que necesito al menos IE 7 el apoyo :) respuesta – cbp

+1

de Boldewyn no funciona en cualquiera de! mis pruebas: los elementos de la lista que resultan son todos del mismo ancho. – rda3000

3

Si usted es feliz usando JavaScript, jQuery podría resolver el problema de la siguiente manera

var $menu, totalwidth; 

$menu = $('ul.menu'); 
totalwidth = ($menu.width()/100); 

$('ul.menu li').each(function(){ 
    this.css('width',String(Math.floor(this.width()/totalwidth))+'%'); 
}); 

$menu.css('width','100%'); 

eso no está probado, pero se ve bien para mí. Comente si tiene alguna pregunta.

+0

El molde de cadena explícito es innecesario, pero de lo contrario, me ganaste; –

+0

Esto probablemente terminará siendo más complicado que esto: $ menu.width() será 100% (aunque el valor real que obtienes será en píxeles) por defecto a menos que flote la UL porque UL es un elemento de bloque.Por lo tanto, tendrá que flotar y luego desplegar el UL para obtener el valor correcto para el ancho total. O puede obtener el ancho total sumando primero el ancho de los elementos LI y luego volviendo a recorrerlos para ajustarlos a un nuevo ancho. – wheresrhys

+0

Eso fue lo primero que pensé, pero no quería hacer dos vueltas ... Flotar y no flotar suena como una apuesta segura, ¿debería editar mi código? – Gausie

1

Creo que la sugerencia de boldewyn debería funcionar. Utilizaría este enfoque para navegadores modernos y luego usaría comentarios condicionales para pasar lo siguiente a ie6/7, para que el navegador se vea bien allí, aunque no abarque el ancho del 100%.

ul { 
    width: 100%; 
} 
li { 
    float:left; // or display:inline-block; 
} 
Cuestiones relacionadas