ugrás a tartalomhoz

css - változó számú menüpontok széthúzása

inf · 2013. Ápr. 29. (H), 07.54
Üdv.

Van egy oldal, aminek a fejléc részében van egy horizontális menü. A menü szélessége 100% az body-hoz viszonyítva (a body fix szélességű). Vannak benne linkek, mint menüpontok. Ezeknek a linkeknek a hossza a rajtuk lévő szöveg hosszától függ, nincs külön gomb háttérkép, vagy bármi ilyesmi. A menüpontok száma változik attól függően, hogy valakinek mihez van joga az oldalon, be van e lépve, stb... A szöveg - ami rajtuk van - is változhat ettől függően.

Több dolog van, ami fontos nekem ezzel a menüvel kapcsolatban:
- szét legyenek húzva a menüpontok a menü teljes szélességében
- a menüpontok közötti hézag egyforma legyen

Jelenleg ezt csak úgy tudom elérni, hogy kézzel állítom be minden egyes menü változatnál minden egyes menüpont szélességét.

Lehetséges ezt valahogy css-el automatizálni?
 
1

Tábla

Hidvégi Gábor · 2013. Ápr. 29. (H), 08.12
Rakd be őket egy száz százalék széles táblába.
2

Köszi!Arra jó, hogy

inf · 2013. Ápr. 29. (H), 09.03
Köszi!

Arra jó, hogy kinyújtsa, de a hézagok nem egyformák a menüpontok között (legalábbis firefox-ban). A hézag nagysága függ a menüpont szélességétől: rövidebb menüpontmellett kisebb lett a hézag, ezt meg szeretném elkerülni.

Hamár itt tartunk, nincs erre valamilyen eszköz css-ben? Muszáj táblázatot használni mondjuk ul-li helyett?

szerk:

Úgy nézem, hogy ul-li-nél is display:table-t használnak erre:
http://stackoverflow.com/questions/5186712/stretch-horizontal-ul-to-fit-width-of-div

szerk2:

Megfelelő számú nbsp-t téve a megfelelő helyre komepnzálható dolog. A hosszabbak mellé 4-6 nbsp kell, a rövidebbek mellé 8-10. Az algoritmusra még nem jöttem rá, nem az egyforma szöveghossz számít. Ez se egy túl automatikus dolog, de azért jobb, mint a semmi...
3

Hézagok

Hidvégi Gábor · 2013. Ápr. 29. (H), 09.22
A táblának szoktam egy border-collapse: collapse; stílust adni, akkor a cellák között nincs rés.
4

A cellák közötti réssel nincs

inf · 2013. Ápr. 29. (H), 09.31
A cellák közötti réssel nincs gond, az állandó... A cellák padding-ja függ a bennük lévő szöveg hosszától, ez a gond... Ezt lehet kompenzálni, ha beteszek néhány plusz nbsp-t a rövidebb szövegű cellákba plusz hézagnak.

Köszi a választ, szerintem ez a kettő így összekombinálva lesz a megoldás.
5

Sajnos ez erősen függ attól,

inf · 2013. Ápr. 29. (H), 09.59
Sajnos ez erősen függ attól, hogy mekkora a táblázat szélessége. Jelen esetben fix, úgyhogy nincs gond, de %-al beállítva és átméretezve az ablakot ez sem működik...
  1. <html>  
  2. <head><title></title></head>  
  3. <body>  
  4. <style>  
  5.     * {  
  6.         margin: 0px;  
  7.         padding: 0px;  
  8.         font-size: 16px;  
  9.     }  
  10.       
  11.     table {  
  12.         width: 800px;  
  13.     }  
  14.       
  15.     td {  
  16.         border: 1px solid blue;  
  17.         text-align: center;  
  18.     }  
  19. </style>  
  20. <table>  
  21.     <tr>  
  22.         <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#">aa</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>  
  23.         <td>&nbsp;&nbsp;<a href="#">aaaaaaaaaaaaa</a>&nbsp;&nbsp;</td>  
  24.         <td>&nbsp;&nbsp;&nbsp;<a href="#">aaaaaaaaa</a>&nbsp;&nbsp;&nbsp;</td>  
  25.         <td>&nbsp;<a href="#">aaaaaaaaaaaaaaaaaa</a>&nbsp;</td>  
  26.         <td>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#">aaaaaa</a>&nbsp;&nbsp;&nbsp;&nbsp;</td>  
  27.         <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#">aaaa</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>  
  28.     </tr>  
  29. </table>  
  30. </body>  
  31. </html>  
A házag így jön ki 1-1 menüpontra:

gap_i = x*length(text_i+nbsp_i) + width(font)*length(nbsp_i)
x = f(width(table), sum(text_i+nbsp_i))
Alapból meg így számol a böngésző:

gap_i = x*length(text_i+nbsp_i)
x = f(width(table), sum(text_i+nbsp_i))
Az a gond ezzel, hogy először összeszámolja az összes szöveg hosszát, utána meg az aktuális cellában lévő szöveghosszát osztja le az összes szöveg hosszával, ahelyett, hogy a cellák számával osztaná le a maradék helyet, és egyenletesen adná a hézagot.
6

Hézag

Hidvégi Gábor · 2013. Ápr. 29. (H), 10.11
Na, azt hiszem, felfogtam, mit értesz hézagon. Én betennék egy scriptet a tábla mögé, ami a cellák szélességét a (100 / cellak_szama)%-ra állítaná.
7

Jó, hát scripttel könnyű...

inf · 2013. Ápr. 29. (H), 10.36
Jó, hát scripttel könnyű... Nyilván ezért tettem fel a kérdést.

Közben kiszórtam stackoverflow-ra is:

http://stackoverflow.com/questions/16274175/css-stretched-and-evenly-spaced-horizontal-menu


Gondolom ott is scriptet fognak mondani elsőnek, más nekem se jut eszembe, de én nem vagyok valami nagy css guru... (Sőt legszívesebben kiszórnám a kukába, és mindenhol kötelezővé tenném js-t, de ez csak az én egyéni véleményem.)
8

Srácok! Szerintem ez a

tiku I tikaszvince · 2013. Ápr. 29. (H), 11.03
Srácok! Szerintem ez a táblázatos menü manapság szakmailag nagyon nehezen toreláható megoldás. A &nbsp;-t formázásra használni… !?

Ha jól értem a problémád, akkor azt szeretnéd, hogy a menü minden eleme azonos szélességű legyen, az elemen belül a tartalom (link) pedig középen legyen. Mivel sem a renderelt szövegek szélessége, sem az elemek száma nem ismert, szerintem legyen egy kis JS, ami az oldal megjelenítésekor elosztja a rendelkezésre álló hely szélességét az elemek számával. A kapott eredmény lesz az aktuális oldalon az elemek szélessége. jQuery-vel ezt így oldanám meg:
  1. jQuery(document).ready(function($){  
  2.   // Feltételezem, hogy a menü rendelkezik egy menu class-al  
  3.   $('ul.menu').each(function(){  
  4.     var $menu = $(this);  
  5.     var items = $menu.find('> li');  
  6.     var itemCount = items.length;  
  7.     var width = Math.floor($menu.width() / itemCount);  
  8.     items.width(width);  
  9.   });  
  10. });  
Így ha rendelkezésre álló szélesség 1000px és van 10 elemed, akkor mindegyik elemed 100px széles lesz.

A CSS formázáskor érdemes figyelni a box modelre! Hogy ne lődd magad térden, érdemes elkerülni, hogy ugyanannak az elemnek (ul > li menü esetén a li elemnek) ne adj fix szélességet és oldalsó margin, padding értékeket. Ha border is van az elemeken, akkor azzal is számolnod kell.

Érdemes lehet a CSS-t úgy megírni, hogy ha valami miatt ez a JS nem futna le, akkor is átlátható legyenek az elemek. Tennék egy kis margint/paddingot a linkekre és az egészet valamelyik irányba rendezném
  • vagy az elemekre tett float szabállyal
  • vagy az elemeket inline-block-ra állítva, a menü text-align beállításával
Másik rendkívül érdekes kérdés, hogy egy ilyen nagyon rugalmasra alakított menü hogyan befolyásolja a használhatóságot. Nem zavarja-e össze a felhasználókat, hogy pl a Főoldal menüpont mindig máshova esik?
11

A kérdést azért tettem föl,

inf · 2013. Ápr. 29. (H), 12.03
A kérdést azért tettem föl, hogy hátha kiderül, hogy js nélkül is megoldható automatizáltan a dolog. Ha js nélkülit szeretnék szerintem szerver oldalra írnom kell egy algoritmust, ami megnézi a szöveghosszakat, és az alapján állít be külön szélességet minden menüpontnak. A másik megoldás, amit te mondasz. Na kb ennyit ér a css... Azért még várok, hátha meg lehet haxolni css-el is ilyenre.
14

Szerintem ez a táblázatos

Hidvégi Gábor · 2013. Ápr. 29. (H), 12.18
Szerintem ez a táblázatos menü manapság szakmailag nagyon nehezen toreláható megoldás. A &nbsp;-t formázásra használni… !?
Van egy probléma, amit táblázattal megoldani a legegyszerűbb, akkor miért ne? Ha tényleg foglalkozol a felolvasóprogramokkal rendelkezőkkel, akkor adsz neki egy role="menu" attribútumot, és máris túl sok bitet pazaroltunk el erre a bagatell dologra, mert rajtuk kívül az égvilágon senkit nem érdekel, hogy milyen tag-ben van a tartalom.

Ahogy inf3rno is említi, sokkal nagyobb probléma, hogy már egy ilyen alapfeladatnál is a css bedobja a törülközőt.
9

Spacing?

Poetro · 2013. Ápr. 29. (H), 11.47
10

Ez nem az, amit szeretnék.

inf · 2013. Ápr. 29. (H), 12.02
Ez nem az, amit szeretnék. Nyilván ha egyforma hosszúak a menüpontok, akkor egyforma a hézag is köztük. Ha jobban megnézed a padding mérete függ a szöveg hosszától, ami a menüpontban van.
12

Lerajzolnád?

Poetro · 2013. Ápr. 29. (H), 12.13
Lerajzolnád? Mert nem igazán értem akkor, hogy mit is szeretnél.

- szét legyenek húzva a menüpontok a menü teljes szélességében
- a menüpontok közötti hézag egyforma legyen

Az én megoldásomban a fentiek teljesülnek. Mindehol 10px a menüpontok közötti távolság, és szét vannak húzva.
13

Valaki megírta:<!DOCTYPE

inf · 2013. Ápr. 29. (H), 12.13
Valaki megírta:
  1. <!DOCTYPE html>  
  2. <html lang="en">  
  3. <head>  
  4. <meta charset="utf-8">  
  5.   
  6. <style media="all">  
  7. ul, li {  
  8.     margin: 0;  
  9.     padding: 0;  
  10. }  
  11. ul {  
  12.     width: 800px;  
  13.     list-style: none;  
  14.     display: table;  
  15.     border-spacing: 5px;   
  16.     text-align: center;  
  17. }  
  18. li {  
  19.     display:  
  20.     table-cell;  
  21. }  
  22. li a {  
  23.     padding: 0 30px;  
  24. }  
  25. </style>  
  26.   
  27. </head>  
  28. <body>  
  29.   
  30. <ul>  
  31.     <li><a href="#">aa</a></li>  
  32.     <li><a href="#">aaaaaaaaaaaaa</a></li>  
  33.     <li><a href="#">aaaaaaaaa</a></li>  
  34.     <li><a href="#">aaaaaaaaaaaaa</a></li>  
  35.     <li><a href="#">aaaaaaaaa</a></li>  
  36.     <li><a href="#">aa</a></li>  
  37.     <li><a href="#">aa</a></li>  
  38. </ul>  
  39.   
  40. </body>  
  41. </html>  
Lövésem sincs, hogy a padding miért segít rajta, de megy. Gondolom csak bizonyos határok között lehet jó, de a szélességet úgyis csak bizonyos határok között változtatom, úgyhogy jó lesz. Kösz mindenkinek!

szerk:

Közben rájöttem, hogy a padding ugyanazt csinálja kb, mint nálam az nbsp. Így sem teljesen azonosak a hézag méretek, de csak akkor tűnik fel, ha nagyon kevés menüpont van nagyon nagy helyen, és nagyon eltérő a szöveg mérete bennük.
16

Auto

Pepita · 2013. Ápr. 29. (H), 21.40
Lövésem sincs, hogy a padding miért segít rajta
Gondolom azért, mert így fix, különben meg auto lenne (lévén table-cell).

Így elvileg mindegyikhez jobbra-balra 30px hézag lesz, addig, míg az összes együtt nem haladja meg a 800px-t. Arra viszont kíváncsi lennék, hogy mit csinál, mikor a 30-as padding-al a teljes hossz csak mondjuk 600px-re jön ki? Két végén nagyobb az üres hely?

A nem törhető szóközt szerintem is hanyagold...

Szerk.: azt mondjuk én sem igazán értettem, hogy miként gondolod elérni az egyforma "hézagot" és azt, hogy kitöltse a szélességet is. Ehhez vagy betűméretet kéne dinamikusan változtatni, vagy kiszámolni az összes "kitöltendő hézagot", majd leosztani a menük száma + 1 -el és ezt az értéket (felét) kell padding-nek megadni. Ez elég nehéz, nem tudom, hogy pl. PHP-ben van-e fv text-width-re (a különböző betűszélességek miatt minden menünek a szöveg és betűtípus szerint kellene a szélességét számolni). Szerintem ez pontosan JS-el sem oldható meg, nemhogy CSS-el. Engedni kell pl. a teljes szélesség kitöltéséből.
17

A fix padding azért működik,

inf · 2013. Ápr. 30. (K), 07.38
A fix padding azért működik, mert jelentősen csökkenti a hézag azon részét, ami függ a menüpontok szélességétől. Mondjuk ha van 5 menüpontod, akkor a 30-as padding 300px-el csökkenti a hézag azon részét, ami függ a menüpontok szélességétől. Ez meg már azért elég látványos eltérés. A hátránya, hogy a menü sokkal kisebb mértékben összenyomható, de ha fix méretre van beállítva, és nem kell átméreteződnie az ablakkal, akkor ez nem sokat számít.

A paddingon kívül a margin is auto, azt ne felejtsd el, szóval ha a padding-ot fix-re rakod, akkor a margin-al nyújtja ki a teljes hosszra...

A hézag méret kiszámolását tényleg nem lehet megoldani szerver oldalon. Kliens oldalon esetleg hozzá lehet csapni egy js-t, ami kiszámolja a linkek méretéből és a menü hosszából, hogy mekkorának kell lennie a hézagnak.

A mostani megoldás sem a legtökéletesebb, majd be kell lőni a padding-ot olyanra, hogy a legtöbb menüpontot tartalmazó változatnál még összenyomható legyen a menü, a legkisebbnél viszont rásegítsen a hézag kialakításra. Azt hiszem menni fog.
18

CSS

Hidvégi Gábor · 2013. Ápr. 30. (K), 09.18
Milyen egyszerű lenne, ha nem ragaszkodnánk a statikus css-hez.
  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
  2. <html>  
  3. <head>  
  4.   <title>Cím</title>  
  5.   <meta http-equiv="Content-Type" content="text/html; charset=utf-8">  
  6.   <meta http-equiv="content-language" content="hu">  
  7.   <meta http-equiv="X-UA-Compatible" content="IE=7">  
  8. </head>  
  9.   
  10. <body>  
  11.   <style>  
  12.     table {  
  13.       border-collapse: collapse;  
  14.     }  
  15.     td {  
  16.       width: expression(function menu_szelesseg() {  
  17.         this.style.width = (100 / this.parentNode.getElementsByTagName('td').length) + '%';  
  18.       }.apply(this));  
  19.       padding: 0px;  
  20.       border: 1px solid red;  
  21.       text-align: center;  
  22.     }  
  23.   </style>  
  24.   <table style="width: 800px;" id="tabla">  
  25.     <tr>  
  26.       <td>Első</td>  
  27.       <td>Második</td>  
  28.       <td>Harmadik</td>  
  29.       <td>Negyedik</td>  
  30.       <td>Ötödik</td>  
  31.     </tr>  
  32.   </table>  
  33.   <br>  
  34.   <table style="width: 80%;" id="tabla2">  
  35.     <tr>  
  36.       <td>Első</td>  
  37.       <td>Második</td>  
  38.       <td>Harmadik</td>  
  39.       <td>Negyedik</td>  
  40.     </tr>  
  41.   </table>  
  42. </body>  
  43. </html>  
19

Mindig ott rontjátok el a

inf · 2013. Ápr. 30. (K), 09.23
Mindig ott rontjátok el a példákat, hogy azonos hosszúságú menüpontokat választotok... :-) Ez sem működik egyébként... Egyáltalán nem ilyen egyszerű a kérdés...

Le kéne mérni a menüpontokat nyújtás nélkül, aztán közéjük tenni egyforma hézagokat, hogy kitöltsék a maradék teret ...
20

Én ezt a hézag-dolgot nem

Hidvégi Gábor · 2013. Ápr. 30. (K), 09.28
Én ezt a hézag-dolgot nem értem, légy szíves, tégy be egy képet, hogyan kéne kinéznie. CSS-ben nem ismerek olyan tulajdonságot, hogy "hézag" vagy "gap".
21

http://stackoverflow.com/ques

inf · 2013. Ápr. 30. (K), 09.59
http://stackoverflow.com/questions/16274175/css-stretched-and-evenly-spaced-horizontal-menu

Az első képen a normál stretch van, a másodikon, amit szeretnék, hogy a szövegek között egyforma legyen a hézag. Azért nincs ilyen css tulajdonság, mert a margin, border, padding összeadva két szomszédos menüpontnál.
22

IE

Hidvégi Gábor · 2013. Ápr. 30. (K), 10.02
A példámat IE-ben nézted?
23

Persze.

inf · 2013. Ápr. 30. (K), 10.10
Persze. Te is megnézheted, csak írd át az egyik menüpontodat "a"-ra, egy másikat meg "aaaaaaaaaaaaaaaaaaaaaaaaaaa"-ra.
24

Gondolkodom

Hidvégi Gábor · 2013. Ápr. 30. (K), 10.19
Ismét úgy érzem: kezdem érteni, mit szeretnél : )
25

Király! Mikor küldöd a

inf · 2013. Ápr. 30. (K), 10.37
Király! Mikor küldöd a lányokat? :D
26

Íme

Hidvégi Gábor · 2013. Ápr. 30. (K), 11.19
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
  <title>Cím</title>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <meta http-equiv="content-language" content="hu">
  <meta http-equiv="X-UA-Compatible" content="IE=7">
</head>

<body>
  <style>
    table {
      border-collapse: collapse;
    }
    td {
      width: expression(function menu_szelesseg() {
        if (this.style.width != 'auto') {
          var tabla = this.parentNode.parentNode.parentNode;
          var tabla_beallitott_szelesseg = tabla.style.width;
          var tabla_szelesseg_px = tabla.offsetWidth;
          tabla.style.width = 'auto';
          var kulonbseg = tabla_szelesseg_px - tabla.offsetWidth;
          var tdk = tabla.getElementsByTagName('td');
          var td_szam = tdk.length;
          var padding = Math.round(kulonbseg / (td_szam * 2));
          tabla.style.width = tabla_beallitott_szelesseg;
          for (var i = 0; i < td_szam; i++) {
            tdk[i].style.width = 'auto';
            tdk[i].style.paddingLeft = tdk[i].style.paddingRight = padding + 'px';
          }
        }
      }.apply(this));
      padding: 0px;
      border: 1px solid red;
      text-align: center;
    }
  </style>
  <table style="width: 800px;" id="tabla">
    <tr>
      <td>Első</td>
      <td>Második</td>
      <td>Harmadik</td>
      <td>Negyedik</td>
      <td>Ötödik</td>
    </tr>
  </table>
  <br>
  <table style="width: 80%;" id="tabla2">
    <tr>
      <td>a</td>
      <td>Második</td>
      <td>Harmadik</td>
      <td>AAAAAAAAAAAAAAAAAAAAAAA</td>
    </tr>
  </table>
</body>
</html>


Szerkesztve: ezzel az a baj, hogy fix méretű a padding.
27

Zsír :-)

inf · 2013. Ápr. 30. (K), 11.27
Zsír :-)