ugrás a tartalomhoz

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

inf3rno · 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

inf3rno · 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

inf3rno · 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,

inf3rno · 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...

<html>
<head><title></title></head>
<body>
<style>
	* {
		margin: 0px;
		padding: 0px;
		font-size: 16px;
	}
	
	table {
		width: 800px;
	}
	
	td {
		border: 1px solid blue;
		text-align: center;
	}
</style>
<table>
	<tr>
		<td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#">aa</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>
		<td>&nbsp;&nbsp;<a href="#">aaaaaaaaaaaaa</a>&nbsp;&nbsp;</td>
		<td>&nbsp;&nbsp;&nbsp;<a href="#">aaaaaaaaa</a>&nbsp;&nbsp;&nbsp;</td>
		<td>&nbsp;<a href="#">aaaaaaaaaaaaaaaaaa</a>&nbsp;</td>
		<td>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#">aaaaaa</a>&nbsp;&nbsp;&nbsp;&nbsp;</td>
		<td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#">aaaa</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>
	</tr>
</table>
</body>
</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ű...

inf3rno · 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:

jQuery(document).ready(function($){
  // Feltételezem, hogy a menü rendelkezik egy menu class-al
  $('ul.menu').each(function(){
    var $menu = $(this);
    var items = $menu.find('> li');
    var itemCount = items.length;
    var width = Math.floor($menu.width() / itemCount);
    items.width(width);
  });
});
Í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,

inf3rno · 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.

inf3rno · 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

inf3rno · 2013. Ápr. 29. (H), 12.13
Valaki megírta:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">

<style media="all">
ul, li {
	margin: 0;
	padding: 0;
}
ul {
	width: 800px;
	list-style: none;
	display: table;
	border-spacing: 5px; 
	text-align: center;
}
li {
	display:
	table-cell;
}
li a {
	padding: 0 30px;
}
</style>

</head>
<body>

<ul>
	<li><a href="#">aa</a></li>
	<li><a href="#">aaaaaaaaaaaaa</a></li>
	<li><a href="#">aaaaaaaaa</a></li>
	<li><a href="#">aaaaaaaaaaaaa</a></li>
	<li><a href="#">aaaaaaaaa</a></li>
	<li><a href="#">aa</a></li>
	<li><a href="#">aa</a></li>
</ul>

</body>
</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,

inf3rno · 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.
<!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() {
        this.style.width = (100 / this.parentNode.getElementsByTagName('td').length) + '%';
      }.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>Első</td>
      <td>Második</td>
      <td>Harmadik</td>
      <td>Negyedik</td>
    </tr>
  </table>
</body>
</html>
19

Mindig ott rontjátok el a

inf3rno · 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

inf3rno · 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.

inf3rno · 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

inf3rno · 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 :-)

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