תפריט נפתח ב-CSS

‏ • 19 בפברואר, 2005

» אני אקדים ואומר שמאמר זה מתאים לאנשים עם ידע מקדים ב-CSS.

בעבר, כשרצינו לבנות "תפריט נופל" היינו צריכים לדעת גם JavaScript. אך לא עוד, כיום אנו יכולים להשתמש אך ורק ב-CSS על-מנת לבנות את התפריט. כל מה שאנו צריכים לעשות הוא להשתמש ב-Pseudo Class. השימוש הנפוץ ביותר שלו הוא בקישורים. לקישורים יש 5 מצבים:

a:linkקישור שטרם "ביקרנו" בו
a:visitedקישור לאחר ש"ביקרנו" בו
a:activeהקישור הפעיל
a:hoverהקישור בעת מעבר עכבר
a:focusהקישור המקבל את הפוקוס (שימוש במקלדת או לחיצה על הקישור).

בעזרת Pseudo Class אנו נסתיר את תת-התפריטים ונראה אותם רק כאשר המשתמש יעבור עם העכבר מעל פריט הרשימה המפעיל את התפריט. עד שנגיע לשלב הביצוע תהיה לכם הבנה לגבי איך התפריט עובד.

בואו נאמר שאנו רוצים לבנות את התפריט של אתר Webmaster.org.il (בצורה מאוד מצומצמת) ואנו רוצים שהוא יפעל בצורה הבאה:

  • לתפריט יהיו 3 רמות
  • נוכל לשנות את התפריט מאנכי לרוחבי בקלות יחסית ובלי לשנות את מבנה ה-html.

את התפריט נבנה בתוך div וניתן לו הגדרת id עם הערך menu. לשם הכנת התפריט אנו נשתמש בפריטי רשימה (li) עבור כל אחד מהקישורים בתפריט שלנו. לכן אנו ניצור רשימה עם חמישה פריטים:

1
2
3
4
5
6
7
8  
<ul>
<li><a href="#">דף הבית</a></li>

<li><a href="#">פורומים</a></li>
<li><a href="#">לוח מודעות</a></li>
<li><a href="#">עזרי בנייה</a></li>
<li><a href="#">מדורים</a></li>
</ul>

אחרי שבנינו את הבסיס נוסיף עוד שני רשימות מתחת לפריט השני והחמישי (פורומים ומדורים) בצורה הזו:

1
2
3
4
5
6
7  
<li><a href="#">פורומים</a>
<ul>
<li><a href="#">פורום משוב</a></li>
<li><a href="#">תכנות צד שרת</a></li>
<li><a href="#">בניית אתרים – צד לקוח</a></li>
</ul>
</li>

שימו לב ששמנו את הרשימה בתוך פריט רשימה (li), ורק אז סגרנו אותה. זה תקין מכיוון שרשימות לא יכולות להיות ילדים של רשימות אבל הם כן יכולות להיות ילדים של פריטי רשימה. זו למעשה הדרך היחידה בה נוכל לקרוא לתפריט בשלב מאוחר יותר ללא צורך להשתמש ב-JavaScript.
לפריט בו שמנו את הרשימה נוסיף class עם הערך submenu. ה-class הזה יהיה המנגנון בו נקרא לתת-התפריטים להופיע.

לכל רשימה (ul) אנו ניתן class שיתאר את ההיררכיה, במדריך זה החלטתי להשתמש ב-first, second וב-third. כאשר firstיהיה ה-class של הרשימה הראשונה, second יהיה ה-class של הרשימה השניה הנמצאת תחת הפריט השני והחמישי. ואת third נשים תחת הפריט השלישי ברשימת ה-second תחת "מדור CSS".

לפני שנעבור הלאה בואו נראה עם מה יש לנו לעבוד:

  • הגדרת id עם הערך menu.
  • הגדרת class עם הערך first.
  • שני הגדרות class עם הערך second.
  • הגדרת class עם הערך third.
  • שלושה הגדרות class עם הערך submenu.

דוגמא

מגדירים את הבסיס

לפני שנתחיל בואו ניתן כמה הגדרות בסיס ל-div בו מתאכסן התפריט שלנו:

1
2
3
4  
div#menu {
float: right;
width: 9.5em;
}

מה שעשינו כאן הוא לגרום לכל התפריט "לצוף" לצד ימין וקבענו את רוחבו ל-9.5em. עכשיו כאשר יש לנו כבר את הבסיס, אנו נוריד את כל הגדרות ה-margin וה-padding לכל הרשימות וניתן גם להם רוחב של 9.5em:

1
2
3
4
5  
div#menu ul {
margin: 0;
padding: 0;
width: 9.5em;
}

אם אתם עוקבים אחר תהליך הבנייה אתם בוודאי תשימו לב שאי אפשר כרגע להבדיל בין התפריטים לתפריטי המישנה. אל דאגה אנו נפתור זאת בעוד רגע.

השלב הבא יהיה למקם את תפריטי המישנה היכן שאנו רוצים אותם. לשם כך נקבע את כל פריטי הרשימה כיחסיים לאלמנט האב:

1
2
3  
div#menu li {
position: relative;
}

כעת מה שאנו רוצים לעשות הוא לקבוע היכן יופיעו תפריטי המישנה. על-כן ניתן הגדרה שתפתח את תפריטי המישנה מהנקודה העליונה של פריט הרשימה בו נמצאת הרשימה שהיא בעצמה תפריט מישנה. נשמע מסובך? לא ממש:

1
2
3
4  
div#menu ul ul {
position: absolute;
top: 0;
}

בשלב זה אתם בוודאי תוהים מדוע אנו מגדירים div#menu במקום #menu. ובכן הסיבה היא שאינטרנט אקספלורר ב-windows לא פותח את תפריטי המישנה. למה זה קורה? לא ברור.

אתם זוכרים שהצבנו בהגדרות הבסיס של ה-div שעוטף את התפריט שלנו width: 9.5em;? ובכן כאן הוא בא לשימוש. כדי לגרום לתפריטי המישנה להופיע בצד ימין של הרשימה, אנו נוסיף לו את המרחק, שהוא למעשה רוחבמתפריט הבסיס:

1
2
3
4
5  
div#menu ul ul {
position: absolute;
top: 0;
right: 9.5em;
}

עכשיו כל תפריטי המישנה שלנו נמצאים היכן שהם אמורים להיות.
לפני שנתקדם בואו נוריד את ההבלטות מהרשימה וכמו-כן נוריד להם את השוליים:

1
2
3
4
5
6
7
8
9
10
11  
div#menu ul {
margin: 0;
padding: 0;
width: 9.5em;
liststyle: none;
}

div#menu li {
position: relative;
margin: 0;
}

דוגמא

הפיכת התפריטים ליותר יפים

לפני שנמשיך בבנייית התפריט, אני רוצה לעצור ולדון בבעיה מסויימת הקיימת באינטרנט אקספלורר. כל הדפדפנים המודרניים מכבדים את אפקט ה-hover מעל כל אלמנט. אינטרנט אקספלורר לעומת זאת מכבד את האפקט אך ורק מעל קישורים. ודבר זה גורם לנו בעיה. הדרך בה אנו נגרום לתפריטי המישנה להופיע היא באמצעות הגדרת hover על פריטי הרשימה (li). כדי לגרום לאינטרנט אקספלורר לכבד את בקשתינו יש צורך להוסיף לו "התנהגות" (behavior).

באתר של פיטר נדרלוף ישנו קובץ behavior (.htc) הפועל על מערכות windows והגורם לאינטרנט אקספלורר לכבד את אפקט hover על כל אלמנט.

הערה: הדפדפן היחידי שהאפקט לא יעבוד עליו הוא אינטרנט אקספלורר למחשבי מקינטוש, אך מכיוון שאחוזי השימוש בו מאוד נמוכים (ואני בספק אם יש עדיין אנשים המשתמשים בו), זוהי הקרבה שמשתלם לעשות.

הצמדת ה-behavior נעשית דרך הגדרת ה-body:

1
2
3  
body {
behavior: url(&quot;csshover.htc&quot;);
}

עכשיו לאחר שאנו יודעים שאינטרנט אקספלורר יכבד את החלטתנו להשתמש ב-hover על פריטי רשימה (li) אנו יכולים לעבור הלאה ולהתחיל לעצב את התפריט שלנו. לשם התחלה בואו נוסיף מסגרת מסביב לכל הרשימות שלנו (ul) וניתן להם רקע.

1
2
3
4
5
6
7
8  
div#menu ul {
margin: 0;
padding: 0;
width: 9.5em;
liststyle: none;
<strong>background: #DAE8F8;
border: 1px solid;</strong>
}

אם אתם עוקבים אחר המדריך, אתם בוודאי שמים לב שהקישורים בתוך התפריט לא מכסים את כל השטח של פריט הרשימה. הסיבה לכך היא שהקישורים הם אלמנטים מסוג inline. על-מנת שנוכל "לפרוס" אותם שיתפסו את כל שטח פריט הרשימה, אנו נדמה אותו לאלמנט block. כמו-כן נוסיף border תחתון בכל פריט רשימה.

הערה: האלמנט ישאר inline אך הדפדפנים יתייחסו אליו כאילו הוא block

1
2
3
4
5
6
7
8
9  
div#menu li a {
display: block;
}

div#menu li {
position: relative;
margin: 0;
borderbottom: 1px solid silver;
}

עכשיו כשהקישורים מדמים עצמם לאלמנט block, אנו יכולים להחיל עליהם עיצובים המתאימים לאלמנטים מסוג block. כדי למקם את הקישורים בצורה סבירה יותר בתוך פריט הרשימה אנו ניתן להם קצת padding וכמו-כן נוריד את הקו התחתון שמתווסף לכל קישור כברירת מחדל.

1
2
3
4
5  
div#menu li a {
display: block;
textdecoration: none;
padding: 0.15em 0.5em 0.15em 0;
}

האפקט הזה יעבוד היטב בדפדפנים שאינם אינטרנט אקספלורר. כדי להתאים את האפקט לאינטרנט אקספלורר אנו ניקבע לו רוחב קבוע ולאחר מכן נבטל את הרוחב לכל הדפדפנים האחרים.

1
2
3
4
5
6
7
8
9
10  
div#menu li a {
display: block;
textdecoration: none;
padding: 0.15em 0.5em 0.15em 0;
width: 9em;
}

div#menu>ul a {
width: auto;
}

מה שעשינו כאן הוא שהסתרנו את הגדרת העיצוב מאינטרנט אקספלורר על-ידי הגדרת child-selector. הגדרה זו פירושה שכל אלמנט a שהוא צאצא של אלמנט ul שהוא בעצמו בן של אלמנט div ויש לו id עם הערך menu. ומכיוון שאינטרנט אקספלורר לא מכיר את הבורר הזה, הוא מתעלם מכל ההגדרה לחלוטין.

הגיע הזמן להכניס את אפקט ה-hover בתפריט שלנו.

1
2
3  
div#menu li:hover {
backgroundcolor: #fcc;
}

זוכרים את ה-behavior שהצמדנו לסגנון ה-body? ובכן כאן הוא נכנס לפעולה. באופן רגיל אינטרנט אקספלורר לא היה מראה שום שינוי בעיצוב, אבל אם תבדקו את הדף תוכלו לראות את האפקט בפעולה.

הערה: מסיבה לא ידועה הגדרת ה-behavior גורמת לאינטרנט אקספלורר להתנהג בצורה משונה כאשר עוברים עם העכבר מעל הפריטים בתפריט שלנו. (הבעיה הזאת מתרחשת רק כאשר משתמשים ב-direction: rtl בתפריטים אנכיים) הדפדפן מנסה לגרום להם "לצוף" שמאלה. דרך אחת לתקן את הבעיה לשנות את הכיוון ל-ltr ואז תהיה לנו בעיה אם נרצה לכתוב עברית ואנגלית ביחד. דרך אחרת היא להכניס float: right, להגדרת פריטי הרשימה (div#menu li). אך אז יש לנו בעיה עם דפדפנים מודרניים. בואו ניתן הגדרה שרק אינטרנט אקספלורר יקרא:

1
2
3  
* html div#menu li {
float: right;
}

ההגדרה הזו, מנצלת באג שנמצא בדפדפני אינטרנט אקספלורר (גרסא 5.01 ומעלה) שלמעשה קורא את ההגדרה בצורה הזו: html div#menu li. והוא אינו אמור להתאים לשום אלמנט. מידע נוסף לגבי הבורר הזה אפשר למצוא באתר CSS Hub.

זה יהיה רעיון טוב להכניס בשלב זה סימון כלשהו כדי שיוכלו להבחין היכן נמצאים אותם פריטים בתפריט אשר נפתחים לתפריטים נוספים. (באפשרותכם להשתמש בגרפיקה מוכנה):

1
2
3  
div#menu li.submenu {
background: url(“submenu.gif”) norepeat center left;
}

כרגע חשוב מאוד סדר ההצבה של הגדרות העיצוב. אם הצבנו את ההגדרה – div#menu li:hover לפני ההגדרה – div#menu li.submenu. התוצאה תהיה שלא נוכל לראות את הצבע מתחלף כאשר אנו עוברים מעל התפריטים הנפתחים לתפריטים נוספים. לכן חשוב מאוד לשים לב לסדר הופעת הגדרות העיצוב.

לפני שנסיים את החלק הנוכחי, אני רוצה להסב את תשומת ליבכם אל דפדפן מוזילה, שמראה פס גלילה רוחבי למרות שאין צורך בו. הסיבה שזה קורה היא בגלל שהדפדפן עדיין קורא את הרשימות שלנו כ-list-item. כדי להעלים את פס-הגלילה, פשוט אפשר להגדיר אותם כ-block:

1
2
3
4
5
6  
div#menu li {
position: relative;
margin: 0;
borderbottom: 1px solid silver;
<strong>display: block;</strong>
}

דוגמא

מסיימים את התפריט

עכשיו עלינו להעלים את תפריטי המישנה כדי שיוכלו להיות תפריט נפתח אמיתי:

1
2
3
4
5
6  
div#menu ul ul {
position: absolute;
top: 0;
right: 9.5em;
display: none;
}

ועכשיו, נראה רק את תפריטי המישנה הרלוונטיים. שימו לב איך אנו מפנים לכל תפריט מישנה בנפרד. אנו עושים זאת בעזרת הפניה ישירה ל-class של פריט הרשימה:

1
2
3  
div#menu ul.first li.submenu:hover ul.second {
display: block;
}

כאשר נעבור על פריטי הרמה הראשונה שיש להם class עם הערך submenu יפתח התפריט מישנה של הרמה השניה הרלוונטית. עכשיו נעשה את אותו הדבר גם לרמה השלישית:

1
2
3
4  
div#menu ul.first li.submenu:hover ul.second,
div#menu ul.second li.submenu:hover ul.third {
display: block;
}

לסיום, כדי שתפריטי המישנה יפתחו בדיוק היכן שאנו רוצים אותם, אנו נוסיף margin שליליים:

1
2
3
4
5
6
7
8
9
10
11  
div#menu ul ul {
position: absolute;
top: 0;
right: 9.5em;
display: none;
margintop:1px;
}

* html div#menu ul ul {
marginright:1px;
}

בדפדפנים כגון מוזילה מספיקה הגדרת margin-top: -1px. אבל דפדפן אינטרנט אקספלורר עדיין לא מציג את התפריט כפי שאנו רוצים. על-כן הוספנו לו הגדרת margin-right: -1px כדי לטפל בבעיה מבלי שזה יפגע בתצוגה בדפדפנים אחרים.

דוגמא

הופכים את התפריט לאופקי

הגיע השלב בו אנו הופכים את התפריט שלנו לאופקי במקום אנכי. דבר ראשון שאנו צריכים לעשות הוא להוריד את הגדרות הרוחב מבסיס התפריט והרשימות:

1
2
3
4
5
6
7
8
9
10
11  
div#menu {
float: right;
}

div#menu ul {
margin: 0;
padding: 0;
liststyle: none;
background: #DAE8F8;
border: 1px solid;
}

עכשיו אנחנו רוצים שפריטי הרשימה שלנו "יצופו" כדי שנוכל לראות אותם אחד ליד השני. בנוסף נוסיף להם רוחב כדי שמראה התפריט שלנו לא ישבר:

1
2
3
4
5
6
7
8
9
10
11  
div#menu {
float: right;
}

div#menu ul {
margin: 0;
padding: 0;
liststyle: none;
background: #DAE8F8;
border: 1px solid;
}

אנחנו רוצים גם שתפריטי המישנה שלנו יתאימו לבסיס. כדי לבצע זאת נוסיף להם רוחב וכמו כן נוריד את הגדרות המיקום:

1
2
3
4
5
6  
div#menu ul ul {
position: absolute;
display: none;
margintop:1px;
width: 9.4em;
}

עכשיו, אם אתם עוקבים אחרי המדריך הזה באמצעות דפדפן אינטרנט אקספלורר, אתם תשימו לב שהתפריט שלנו נעלם ותווספה לנו גלילה רוחבית. כדי לתקן את התקלה אנחנו פשוט נוסיף הגדרת רוחב של 100% לתפריט שלנו:

1
2
3
4  
div#menu {
float: right;
width: 100%;
}

כרגע תפריט הבסיס שלנו נראה שקוף. זה נגרם בגלל שגרמנו לפריטי הרשימה שלנו "לצוף". לכן פשוט נוסיף גבול ורקע לתפריט הבסיס:

1
2
3
4
5
6  
div#menu {
float: right;
width: 100%;
border: 1px solid silver;
background: #DAE8F8;
}

בשלב הזה, אפשר לראות בבירור שיש לנו גבול כפול בתפריט הבסיס. אנו פשוט נוריד את הגבול העליון והתחתון ונגדיר צבע עדין יותר וכמו כן נוריד את הגבול מפריטי הרשימה שלנו לחלוטין:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16  
div#menu ul {
margin: 0;
padding: 0;
liststyle: none;
background: #DAE8F8;
border: solid silver;
borderwidth: 0 1px;
{

div#menu li {
position: relative;
margin: 0;
display: block;
float: right;
width: 9.5em;
}

אחרי שהורדנו את הגבולות בתפריט הם בהחלט חסרים, לכן נוסיף הגדרה חדשה כדי להשלים את מראה התפריט:

1
2
3  
div#menu ul ul li {
borderbottom: 1px solid silver;
}

עכשיו, אנחנו יכולים לראות בבירור שהחץ שלנו (אם השתמשתם בו) כבר לא מתאים לתפריט הבסיס. עם זאת הוא כן מתאים לתפריט המישנה. על כן אנו נשנה שתי הגדרות (באפשרותכם להשתמש בגרפיקה מוכנה):

1
2
3
4
5
6
7  
div#menu li.submenu {
background: url(&quot;submenu_down.gif&quot😉 norepeat center left;
}

div#menu li.submenu li.submenu {
background: url(&quot;submenu&quot😉 norepeat center left;
}

כמו-כן נוסיף הגדרה לאפקט ה-hover, שכן הרקע נעלם בעת מעבר העכבר:

1
2
3  
div#menu li.submenu li.submenu:hover {
backgroundcolor: #fcc;
}

הגיע הזמן למקם את התפריטים שלנו במקומם הנכון. לכן ניתן שתי הגדרות חדשות לתפריטי המישנה ברמה השניה והשלישית:

1
2
3
4
5
6
7
8
9  
div#menu ul.second {
top: 1.5em;
right:1px;
}

div#menu ul.third {
top: 0;
right: 9.55em;
}

מה שעשינו כאן, הוא שגרמנו לכל רמה להפתח בדיוק היכן שרצינו אותה. כרגע חסר גבול עליון בתפריטי המישנה שלנו. בואו נוסיף אותו:

1
2
3
4
5
6
7  
div#menu ul ul {
position: absolute;
display: none;
margintop:1px;
width: 9.4em;
bordertop: 1px solid silver;
}

לסיום נתקן את המיקום של פריטי הרשימה על-ידי כיוון ה-margin של פריטי הרשימה:

1
2
3
4
5
6
7  
div#menu li {
position: relative;
margin: 01px 0 0;
display: block;
float: right;
width: 9.5em;
}

דוגמא

תגיות: , ,

תגובות בפייסבוק