• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Prośba o sprawdzenie kodu paska nawigacyjnego

Object Storage Arubacloud
0 głosów
277 wizyt
pytanie zadane 6 stycznia 2018 w HTML i CSS przez kevin Mądrala (5,010 p.)

Witam!

    Mam prośbę o sprawdzenie kodu paska nawigacyjnego. Jest to mój pierwszy pasek zrobiony na Flexy z dwiema zagnieżdżonymi listami. Nie jestem pewny czy nie narobiłem kwiatków i nie za bardzo wiem jak wyświetlić menu trzeciego stopnia z lewej strony. W kodzie css są komentarze które wyjaśniają od czego jest dana klasa i czy czegoś nie jestem pewien.

Kolejna sprawa to nie wiem jak za pomocą flexy część elementów wyświetlić z lewej a część z prawej strony. Dwa elementy są "Do prawej !" chcę umieścić z prawej strony.

https://jsfiddle.net/adriansikora344/6vqm1mkm/

 

Z poważaniem.

 

2 odpowiedzi

0 głosów
odpowiedź 6 stycznia 2018 przez imklau Nałogowiec (42,090 p.)

Pierwsze co się strasznie rzuca w oczy to Twój kod CSS i:

.main-navigation-bar ul li:hover > ul a {
  color: black;
}

Dodawaj klasy do każdego stylowanego elementu tak, żeby uniknać takiego zagnieżdżania selektorów, bo trudno się w tym połapać. Kod powinien wyglądać tak:

.jakas-klasa-li:hover > .jakas-klasa-a {
  color: black;
}

Kolejna rzecz to:

.main-menu {
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  justify-content: flex-start;
}

Tak naprawdę wystarczy sama pierwsza właściwość, bo reszta którą wpisałeś i tak ma dokładnie te wartości na starcie.

Elementy <li> :

.main-menu li { 
  display: block; 
  list-style-type: none;
}

I tak są blokowe więc to display jest tutaj niepotrzebne.

 

Co do tych dwóch elementów po prawej to ja bym w <nav> dała jednak dwie listy <ul> i dla nav dała flexa z justify-content: space-between i tyle :P

komentarz 6 stycznia 2018 przez Comandeer Guru (600,810 p.)

Elementy li mają domyślnie display: list-item, nie zaś block.

komentarz 6 stycznia 2018 przez imklau Nałogowiec (42,090 p.)
:o nawet nie wiedziałam, że takie coś istnieje... dzięki!
0 głosów
odpowiedź 7 stycznia 2018 przez kevin Mądrala (5,010 p.)

Witam!

     Poprawiłem trochę kod i bardziej go opisałem aby lepiej było mi wyjaśnić z czym mam problem co sprawia mi zagmatwanie i czego nie rozumiem. Jeżeli ktoś miałby chwilę wolnego czasu to proszę o ocenę kodu i proszę o pomoc w pytaniach które zadaję tutaj:

1. Prosty pasek nawigacyjny
    Kod na jsfiddle.net: https://jsfiddle.net/adriansikora344/h3cqu457/

2. Pasek nawigacyjny z listą rozwijaną
    Kod na jsfiddle.net: https://jsfiddle.net/adriansikora344/ycLhf5dj/

3. Pasek nawigacyjny z podwójną listą rozwijaną
    Kod na jsfiddle.net: https://jsfiddle.net/adriansikora344/du1wwtby/

 

1. Prosty pasek nawigacyjny

Cel:

Zwykłe menu przypięte z prawej strony pojemnika w którym się znajduje z podświetleniem przycisku nad którym znajduje się kursor.

Kod na jsfidlle.net: https://jsfiddle.net/adriansikora344/h3cqu457/

Kod HTML:

<header>
  <nav class="main-navigation-bar">
    <ul class="main-menu">
      <li><a>Element 1</a></li>
      <li><a>Element 2</a></li>
      <li><a>Element 3</a></li>
      <li><a>Element 4</a></li>
    </ul>
  </nav>
</header>

Wyjaśnienie:

- W kodzie HTML nie ma żadnych odnośników do innych podstron ponieważ kliknięcie w element menu powoduje wywołanie funkcji JavaScript otwierające np. okienko typu modal;

- Znacznik header nie powinien wprowadzać żadnego stylu wpływającego na cechę/wygląd elementu. Nadany styl temu znacznikowi powinien jedynie dokować element w odpowiednim miejscu lub określać rozmiar nagłówka ( w tym przypadku menu ).

- Klasa .main-navigation-bar ustawia szerokość menu na szerokość pojemnika w którym się znajduje oraz ustawia kolor tła który będą dziedziczyć poszczególne elementy listy. Kolor tła jest ustawiany w tej klasie ponieważ w przypadku ustawienia cechy padding dla tej klasy tło będzie wystawać nad/pod elementy menu:

.main-navigation-bar { width: 100%; background: #777; }

Pytanie:

1.0 Czy tutaj width: 100%; jest potrzebne ? Jeżeli dokuję elementy do prawej strony to czy nie jest tak że szerokość paska nawigacyjnego automatycznie przyjmuje maksymalną wartość elementu rodzica ?

- Klasa .main-menu odpowiada za ustawienie trybu wyświetlania listy, położenia:

.main-menu {

display: flex;

justify-content: flex-end;

list-style-type: none;
}

- Ostylowanie poszczególnych elementów listy:

 

.main-menu > li { color: white; cursor: pointer; }
.main-menu > li:hover { color: black; background: #ddd; }
.main-menu > li:active { color: white; background: black; }
.main-menu > li > a {

/* czemu tutaj nie mogę dodać padding jeżeli nie ustawię flagi display:flex/block ? */

display: flex;

padding: 20px;

text-align: center;
text-decoration: none;
}

Element <a> w liście nie ma wpisanej informacji odnośnie koloru czcionki oraz koloru tła. Dziedziczy on te cechy z elementu rodzica czyli <li> co skutkuje również zmianą tych cech poprzez pseudoklasę :hover oraz :active elementu <li> w którym znajduje się omawiany znacznik <a>. Pseudoklasa :hover i :active do zmiany wyglądu nie jest bezpośrednio nadana elementowi <a> ponieważ zmieniając wtedy tło elementu zmieniło by się tylko tło tekstu a nie cały przycisk.

Pytania:

1.1 Tutaj zastanawia mnie dlaczego ustawiając np. padding: 30px; w klasie .main-menu>li> a to zmienia się jedynie szerokość elementu a nie jego wysokość ? Problem przestaje istnieć jeżeli w tej klasie dodam cechę display: flex/block; wtedy bez problemu mogę ustawić padding dla elementu <a>. Dlaczego tak się dzieje ?

 

1.2 Tutaj jest rozbicie menu na dwie klasy, tylko co jeżeli chciałbym mieć na stronie drugie menu ? Nie mogę już użyć klasy .main-menu. Rozwiązaniem na to jest albo nadanie innej nazwy klasy albo dodanie .main-navigation-bar > .main-menu co powoduje „zaciemnienie” kodu.Jedyne rozwiązanie to preprocesory ? Czy to normalne że jest pełno selektorów w stylu ?

 

2. Pasek nawigacyjny z listą rozwijaną

Cel:

Dodanie do poprzedniego paska nawigacyjnego listy rozwijanej. Zadokowanie listy rozwijanej tak aby prawy koniec menu przylegał do prawej krawędzi menu rozwijanego ( wystawał i zwiększał swoją szerokość z lewej strony a nie jak jest standardowo z prawej ).

Kod na jsfiddle.net: https://jsfiddle.net/adriansikora344/ycLhf5dj/

Kod HTML:

<header>
  <nav class="main-navigation-bar">
    <ul class="main-menu">
      <li><a>Element 1</a></li>
      <li><a>Element 2</a></li>
      
      <li class="menu-item-has-children">
        <a>Element 3</a>
        
        <ul class="sub-menu">
          <li><a>sub 1</a></li>
          <li><a>sub 2 bardzo długi element</a></li>
          <li><a>sub 3</a></li>
          <li><a>sub 4</a></li>
          <li><a>sub 5</a></li>
        </ul>
      </li>
      
      <li><a>Element 4</a></li>
    </ul>
  </nav>
</header>

Wyjaśnienie:

Rozwijane menu to nic innego jak zagnieżdżona lista z domyślną flagą display: none; która zmienia się na display: block; przy aktywacji pseudoklasy :hover elementu rodzica tej listy.

- Klasy .main-navigation-bar oraz .main-menu są identyczne jak w poprzednim przykładzie. Różni się tylko klasa .main-menu > li ponieważ została do niej dodana flaga display: block; ponieważ domyślnie ukryta lista z rozwijanym menu ma być wyświetlona bezpośrednio pod elementem <a>.

Pytania:

2.0 Czy te display: block jest tutaj potrzebne ? Podobno jest już tutaj domyślnie ustawione. Jeżeli chciałbym mieć rozwijane menu kolejnego stopnia to bardziej pasuje tutaj flaga display: flex; ponieważ bez problemu mogę wybierać kierunek menu, czy column czy block. Zgadza się ?

- NOWA KLASA: .menu-item-has-children dodaje ona strzałkę informującą użytkownika o tym że ten element zawiera rozwijane menu.

.menu-item-has-children > a:after { content: '\25BC'; padding-left: 10px; }

Selektor > został użyty aby strzałka została dodana do pierwszego napotkanego elementu <a>.Ta klasa służy też do wyświetlenia rozwijanego menu które domyślnie ma ustawioną flagę display: none;

.main-menu > .menu-item-has-children:hover > .sub-menu {
display: block;
padding-left: 0; /* Dlaczego jeżeli nie mam tutaj tego ustawionego to text nie przylega do lewej krawędzi ? */
}

Pytania:

2.1 Skoro używam flex’y to tutaj nie powinienem mieć display: flex; z atrybutem column ? Patrząc na inne przykłądy to wszędzie jest display: block; Ponieważ lista musi być wyświetlona pod elementem <a>. ( Pytam o to co wcześniej )

2.2 Dlaczego jeżeli nie mam tutaj ustawionej flagi padding-left 0; to text nie przylega do lewej krawędzi ? Tylko jest wyświetlany od środka ?

- Klasa .sub-menu

.sub-menu {

display: none;

position: absolute;
z-index: 1;

list-style-type: none;
background: white; /* Kolor tła nie jest dziedziczony ! */
}

Pytanie: 2.3 Dlaczego kolor tła nie jest dziedziczony ? Przecież jest ustawiony w klasie .main-navigation-bar.

 

.sub-menu > li { display: flex;}
.sub-menu > li:hover { background: black; color: white; }

.sub-menu > li > a {
 	 padding: 20px;
  	text-align: center;
  	text-decoration: none;
}

Pytania:

2.4 Rozwijana lista ma szerokość najdłuższego elementu i rozciąga się w prawą stronę. Przylega lewą krawędzią do lewej krawędzi elementu <a> który rozwija tą listę tylko jak zrobić aby lista przylegała do tego elementu prawą krawędzią i rozciągała się w lewą stronę ?

2.5 Tutaj nie jest dodany żaden tag position: relative; dla elementu rozwijającego listę. Czy on musi być ? Dodanie tej flagi skutkuje że szerokość rozwijanej listy jest taka sama jak szerokość przycisku rozwijanego. Mogę zmienić tą szerokość zmieniając width elementu. Ale wolę aby została automatycznie ustawiona na szerokość najdłuższego elementu.

 

3. Pasek nawigacyjny z podwójną listą rozwijaną

Cel:

Rozwijane menu trzeciego stopnia tak aby było wyświetlane z lewej strony

Kod na jsfiddle.net: https://jsfiddle.net/adriansikora344/du1wwtby/

Kod HTML:

<header>
  <nav class="main-navigation-bar">
    <ul class="main-menu">
      <li><a>Element 1</a></li>
      <li><a>Element 2</a></li>
      
      <li class="menu-item-has-children">
        <a>Element 3</a>
        
        <ul class="sub-menu">
          <li><a>sub 1</a></li>
          
          <li class="menu-item-has-children">
            <a>sub 2 - bardzo długi element</a>
          
            <ul class="second-st-sub-menu">
              <li><a>sub 1</a></li>
              <li><a>sub 2</a></li>
              <li><a>sub 3</a></li>
              <li><a>sub 4</a></li>
              <li><a>sub 5</a></li>
            </ul>
          </li>

          <li><a>sub 3</a></li>
          <li><a>sub 4</a></li>
          <li><a>sub 5</a></li>
        </ul>
      </li>
      
      <li><a>Element 4</a></li>
    </ul>
  </nav>
</header>

Wyjaśnienie:

- NOWE KLASY . second-st-sub-menu jest to klasa reprezentująca wyświetlenie menu trzeciego stopnia. Zasada działania jest identyczna jak poprzednio.

Klasa ta jest osadzona w elemencie <li> który ma ustawioną flagę display: flex; więc menu trzeciego stopnia będzie przylegało do elementu <li> który zawiera tą klasę. Teoretycznie aby wyświetlić te menu z lewej strony należy nadać flex-direction: row-reverse ale nie wiem czemu to nie działa.

- Wyświetlenie menu trzeciego stopnia

.sub-menu > .menu-item-has-children:hover > .second-st-sub-menu { display: block; }

Pytanie:

3.0 Tak jak poprzednio, skoro używam już flex’y to nie powinienem użyć tutaj flagi display: flex; a atrybutem column ? ( pytam o to co poprzednio )

- Klasa reprezentująca menu trzeciego stopnia:

.second-st-sub-menu {
  	display: none;
  	position: absolute;
  	z-index: 1;
  
  	margin: 0 0 0 100%; /* Wyświetlenie menu z prawej strony */
  	padding-left: 0; /* Bez wyzerowania padding-left menu odstaje, dziedziczy od lementu <a> ? */
}

Pytania:

3.1 Tak jak w kodzie css, jak wyświetlić menu z lewej strony ?

3.2 Bez flagi padding-left: 0; menu odstaje od reszty, dziedziczy od elementu <a> ?

1
komentarz 7 stycznia 2018 przez Comandeer Guru (600,810 p.)

- W kodzie HTML nie ma żadnych odnośników do innych podstron ponieważ kliknięcie w element menu powoduje wywołanie funkcji JavaScript otwierające np. okienko typu modal;

W takim wypadku bardziej pasowałoby button (które służy do wywoływania jakiejś akcji) niż a (który służy do przechodzenia na inną podstronę lub do innego miejsca danej strony). Zwłaszcza, że a:not([href]) nie jest np. focusowalne z poziomu klawiatury, co znacząco obniża dostępność.

1.0 Czy tutaj width: 100%; jest potrzebne ? Jeżeli dokuję elementy do prawej strony to czy nie jest tak że szerokość paska nawigacyjnego automatycznie przyjmuje maksymalną wartość elementu rodzica ? 

Tak, elementy blokowe domyślnie rozciągają się na 100% swojego rodzica.

Element <a> w liście nie ma wpisanej informacji odnośnie koloru czcionki oraz koloru tła. 

W tym wypadku tak, ale elementy a domyślnie nie dziedziczą koloru czcionki. Tutaj dziedziczą, bo nie są linkami (nie mają atrybutu [href]).

1.1 Tutaj zastanawia mnie dlaczego ustawiając np. padding: 30px; w klasie .main-menu>li> a to zmienia się jedynie szerokość elementu a nie jego wysokość ? Problem przestaje istnieć jeżeli w tej klasie dodam cechę display: flex/block; wtedy bez problemu mogę ustawić padding dla elementu <a>. Dlaczego tak się dzieje ?

Bo linki domyślnie są elementami liniowymi (display: inline), które nie mogą przyjmować dowolnie rozmiarów, dostosowując się do zawartego w nich tekstu. 

1.2 Tutaj jest rozbicie menu na dwie klasy, tylko co jeżeli chciałbym mieć na stronie drugie menu ? Nie mogę już użyć klasy .main-menu 

No ale to jest główne menu. Ile chcesz mieć głównych menu na stronie? ;) Tutaj polecałbym zapoznać się z jakąś metodyką pisania CSS-a, np. BEM czy SMACSS.

Dodatkowo warto zauważyć, że w każdym z tych przykładów przy obecnym kodzie można opuścić header i zostawić  samo nav.

Rozwijane menu to nic innego jak zagnieżdżona lista z domyślną flagą display: none; która zmienia się na display: block; przy aktywacji pseudoklasy :hover elementu rodzica tej listy. 

Taka mała dygresja: a co z urządzeniami mobilnymi, które niekoniecznie rozumieją :hover?

NOWA KLASA: .menu-item-has-children dodaje ona strzałkę informującą użytkownika o tym że ten element zawiera rozwijane menu. 

Osobiście unikałbym takich selektorów i postarał się robić jak najbardziej płaskie. W tym wypadku klasę dodającą strzałkę dodawałbym bezpośrednio na a.

2.1 Skoro używam flex’y to tutaj nie powinienem mieć display: flex; z atrybutem column ? Patrząc na inne przykłądy to wszędzie jest display: block; Ponieważ lista musi być wyświetlona pod elementem <a>. ( Pytam o to co wcześniej ) 

Możesz spróbować z flexem.

2.2 Dlaczego jeżeli nie mam tutaj ustawionej flagi padding-left 0; to text nie przylega do lewej krawędzi ? Tylko jest wyświetlany od środka ? 

Bo każda lista ma domyślny padding i margin.

Pytanie: 2.3 Dlaczego kolor tła nie jest dziedziczony ? 

Bo dopóki tego dziedziczenia nie wymusisz (background-color: inherit), to tło nie jest dziedziczone. Wydaje się, że jest dziedziczone, bo domyślnie jest ustawiane na przezroczyste.

2.4 Rozwijana lista ma szerokość najdłuższego elementu i rozciąga się w prawą stronę. Przylega lewą krawędzią do lewej krawędzi elementu <a> który rozwija tą listę tylko jak zrobić aby lista przylegała do tego elementu prawą krawędzią i rozciągała się w lewą stronę ?

Pokombinowałbym z pozycjonowaniem albo różnymi opcjami dla fleksa.

2.5 Tutaj nie jest dodany żaden tag position: relative; dla elementu rozwijającego listę. Czy on musi być ? 

Jeśli będziesz pozycjonował submenu, to tak – musi być. W innym wypadku – niekoniecznie.

- NOWE KLASY second-st-sub-menu jest to klasa reprezentująca wyświetlenie menu trzeciego stopnia.

A czemu nie zrobisz "uniwersalnego" menu i nie użyjesz .submenu? Dzięki takiemu reużyciu będzie IMO łatwiej ogarnąć kod i stworzyć nielimitowaną liczbę zagłębień.

3.1 Tak jak w kodzie css, jak wyświetlić menu z lewej strony ?

 

order w CSS?

3.2 Bez flagi padding-left: 0; menu odstaje od reszty, dziedziczy od elementu <a> ? 

Nie, to znowu domyślny padding listy. 

komentarz 8 stycznia 2018 przez kevin Mądrala (5,010 p.)

Dziękuje za odpowiedź. Poprawię kod.. Mam tylko pytanie jeszcze odnośnie

    2.5 Tutaj nie jest dodany żaden tag position: relative; dla elementu rozwijającego listę. Czy on musi być ?

Jeśli będziesz pozycjonował submenu, to tak – musi być. W innym wypadku – niekoniecznie.

Mógłbyś dokładniej to rozwinąć ? W tym kontekście nie rozumiem o co chodzi z tym pozycjonowaniem. Jeżeli teraz nie mam ustawionego position: relative to element z position: absolute odnosi się do całego okna a nie do elementu rodzica. Tylko po dodaniu position relative w jaki sposób uzyskać efekt automatycznego zwiększania się rozmiaru elementu sub-menu <a>/<li> przy dodawaniu dłuższego tekstu tak aby się nie zawijał tylko zwiększał się rozmiar pojemnika w którym jest text.

komentarz 8 stycznia 2018 przez Comandeer Guru (600,810 p.)

Mógłbyś dokładniej to rozwinąć ? W tym kontekście nie rozumiem o co chodzi z tym pozycjonowaniem.

Odnosiłem się do mojej poprzedniej odpowiedzi. 

komentarz 24 stycznia 2018 przez kevin Mądrala (5,010 p.)

Z powodu sesji na studiach na chwilę porzuciłem temat. Poprawiłem wyświetlanie się menu od prawej do lewej a nie tak jak jest standardowo od lewej do prawej. Zastanawia mnie dlaczego elementu które mają position: absolute z góry przyjmują na sztywno szerokość elementu z position relative; Mogę zmienić szerokość za pomocą width: AApx; ale co jeżeli chciałbym aby szerokość listy rozwijanej dostosowywała się do najszerszego elementu ? Ustawienie min-width oraz max-width powoduje zawinięcie się tekstu na najbliższym białym znaku. Dlaczego tak jest ?

https://jsfiddle.net/adriansikora344/r5rc30vw/

.sub-menu > li {
  
  min-width: 200px;
  max-width: 8000px;
}

 

Podobne pytania

0 głosów
1 odpowiedź 109 wizyt
0 głosów
1 odpowiedź 274 wizyt
pytanie zadane 2 stycznia 2018 w HTML i CSS przez kevin Mądrala (5,010 p.)
0 głosów
1 odpowiedź 495 wizyt

92,555 zapytań

141,403 odpowiedzi

319,557 komentarzy

61,940 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...