01/10/2018, 08:14

Hỏi về đoạn code menu dropdown by HTML, CSS

Tình hình là e đang mày mò tới phần menu dropdown trong CSS nhưng thấy nó phức tạp sao ý, e thử tự code thì nó rối tùm lum, thế là lên mạng search thì có 1 đoạn code như sau:

<!DOCTYPE html>
<html>
<head>
  <title>Menu Dropdowns</title>
  <style>
    * {
      margin: 0;
      padding: 0;
      -webkit-box-sizing: border-box;
      -moz-box-sizing: border-box;
      box-sizing: border-box;
    }
    ::selection {
      background-color: #A39B9B;
    }
    ::-moz-selection {
      background-color: #A39B9B;
    }
    .menu {
      width: 100%;
      height: auto;
      position: fixed;
      text-align: center;
      font-weight: bold;
      top: 0;
    }
    .menu .list {
      list-style-type: none;
      word-spacing: -4px;
      background-color: #000000;
    }
    .menu .list > li {
      word-spacing: 0;
      display: inline-block;
    }
    .menu .list li a {
      display: block;
      padding: 20px 50px;
      text-decoration: none;
      color: #FFFFFF;
    }
    .menu .list li a:hover {
      background-color: #031C24;
      -webkit-transition: all 0.3s;
      -moz-transition: all 0.3s;
      -o-transition: all 0.3s;
      transition: all 0.3s;
    }
    .menu .list .dropdown .sub-menu {
      list-style-type: none;
      position: absolute;
      background-color: #000000;
      z-index: 1;
      display: none;
      -webkit-box-shadow: 7px 7px 15px grey;
      -moz-box-shadow: 7px 7px 15px grey;
      box-shadow: 7px 7px 15px grey;
    }
    .menu .list .dropdown:hover .sub-menu {
      display: block;
    }
    .menu .list .dropdown:hover > a {
      background-color: #031C24;
    }
    .menu .list .dropdown .sub-menu li a:hover {
      background-color: #CC1B1B;
    }
    p {
      margin: 70px 50px 10px 50px;
    }
  </style>
</head>
<body>
  <div class="menu">
    <ul class="list">
      <li><a href="#">Home</a></li>
      <li><a href="#">About</a></li>
      <li class="dropdown">
        <a href="#">Services</a>
        <ul class="sub-menu">
          <li><a href="#">Education</a></li>
          <li><a href="#">Open Source</a></li>
          <li><a href="#">Software Solution</a></li>
        </ul>
      </li>
      <li class="dropdown">
        <a href="#">FAQ</a>
        <ul class="sub-menu">
          <li><a href="#">License</a></li>
          <li><a href="#">Copyright</a></li>
        </ul>
      </li>
      <li><a href="#">Contact</a></li>
    </ul>
  </div>
  <p>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse feugiat tempus lectus venenatis pharetra. In nec velit nisl. Ut elementum vel nisi quis commodo. Praesent nec dolor nec dui sollicitudin aliquet. Aliquam velit urna, aliquam non hendrerit nec, fermentum vitae enim. Nulla eget erat sed augue maximus feugiat. In egestas lorem non nisl volutpat, sed commodo lorem luctus. Integer consectetur nibh eu urna vestibulum consectetur. Maecenas egestas at orci a auctor. Nullam imperdiet faucibus est, vitae commodo justo dapibus sed.Aliquam erat volutpat. Proin ullamcorper placerat nulla venenatis consequat. In maximus turpis elit, vel varius quam egestas in. Vivamus vitae nibh blandit, porttitor diam et, ultrices dui. Nam luctus dolor nec ante auctor scelerisque. Cras rhoncus elit eget egestas dignissim. Mauris ut ultrices massa. Phasellus rhoncus ante sed justo egestas, eget cursus dui porttitor. Sed condimentum facilisis fringilla.Sed a placerat nisl. Pellentesque id nibh felis. Morbi vel congue enim, eget lobortis ligula. Cras leo eros, pellentesque at molestie vitae, pharetra id felis. Ut non leo euismod, maximus nulla vel, mattis sapien. Suspendisse neque libero, maximus non rhoncus tempus, euismod non massa. Fusce maximus varius scelerisque. Praesent consectetur ipsum velit, eu congue ipsum congue in. Pellentesque molestie nibh eget mollis lacinia. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Integer rhoncus tortor at cursus pellentesque. Fusce convallis, massa eu ullamcorper dapibus, est massa sagittis ex, ac consectetur ipsum odio eget odio. Sed magna est, rutrum quis pharetra in, cursus nec neque.Nunc faucibus nec dui at iaculis. Morbi venenatis sapien sit amet eros rhoncus, sed ullamcorper sem pulvinar. Suspendisse nec bibendum quam. Nunc scelerisque tempor justo eu suscipit. Praesent suscipit porttitor rutrum. Nullam efficitur quam ut ante viverra, at volutpat eros fermentum. Quisque id erat augue.Aliquam ut leo non elit consequat finibus. Ut hendrerit arcu erat, varius fermentum nulla iaculis ac. Mauris iaculis urna vel ex maximus, id lobortis libero ornare. Vivamus convallis nulla nec cursus aliquam. Proin nunc metus, fermentum eu ullamcorper ut, vehicula eu libero. Sed vitae volutpat purus. Aenean dictum ut orci eget sodales. Proin posuere, mi id luctus sagittis, nibh turpis mollis lectus, vel tristique quam diam in erat. Sed dapibus luctus ullamcorper. Nam auctor augue vitae metus maximus tristique. Curabitur at auctor nisi.Vivamus rutrum mattis magna eget gravida. Ut at dui facilisis, eleifend turpis in, sollicitudin nulla. Fusce viverra tortor a tellus lacinia, sit amet faucibus eros pharetra. Vestibulum eget tincidunt eros, id auctor mi. Donec dictum justo vitae magna bibendum, in commodo leo semper. Aliquam suscipit rutrum leo ut volutpat. Nam tellus eros, pretium quis dignissim nec, varius sed magna.In porta mauris id tincidunt posuere. Aliquam lacus ipsum, vehicula a lectus a, facilisis fringilla nisi. Nulla tristique at odio quis elementum. Vivamus pretium maximus ante. Cras vitae varius sem. Donec tempor nibh quis justo blandit venenatis sit amet sit amet nisi. Integer molestie quam quis nibh blandit placerat. Aliquam eget libero porttitor, auctor metus vitae, ullamcorper nibh. Sed urna nunc, scelerisque in sodales sed, ultricies nec eros. Nam lobortis posuere nisi vel maximus. Nulla a dolor tempus, finibus tortor at, fringilla metus.Mauris massa mauris, feugiat eu ligula ut, posuere laoreet arcu. Ut feugiat imperdiet odio, non eleifend sem sollicitudin quis. Fusce non dignissim velit. Morbi faucibus elementum arcu, malesuada sollicitudin tortor. Donec sit amet nulla consequat, gravida mi quis, varius urna. Aenean feugiat lobortis turpis. Fusce nisi nulla, molestie et tortor quis, cursus aliquam libero. Quisque a ullamcorper mauris. Sed a lacinia tortor, non tempor nulla. Ut ut orci dui. Donec maximus vestibulum elit ac ultrices.Aenean at nisl lorem. Integer fringilla velit eget mattis hendrerit. Aenean dui risus, imperdiet imperdiet nulla sit amet, condimentum pretium leo. In velit nisl, pellentesque vel dui eget, tempor fermentum mauris. Duis feugiat ante sit amet lorem cursus malesuada. Proin vitae felis eu dolor semper congue. Nunc pellentesque velit tellus, vitae molestie justo placerat et. Cras sagittis magna at turpis consequat consectetur. In iaculis ipsum elit, tempus laoreet orci pellentesque accumsan.Morbi venenatis posuere dui, et ornare libero imperdiet eget. Duis efficitur eget ante nec gravida. Sed vestibulum pellentesque odio, ac lacinia libero. Quisque pretium velit a metus tempus, ut scelerisque lectus rutrum. Aenean dapibus, lacus eu semper vehicula, dolor est convallis leo, in auctor sapien eros id elit. Duis ipsum quam, tempor sit amet lectus non, vestibulum rutrum ex. Etiam varius feugiat quam, eu convallis tortor ultricies id. Aenean congue eros vitae ornare facilisis. Donec interdum in justo in tincidunt. Donec viverra nulla eu enim tempor cursus. Maecenas dapibus velit augue, ac eleifend lacus convallis sit amet. Donec consequat nulla sit amet ligula dapibus scelerisque. In fringilla fermentum diam, ac vehicula tortor luctus eget. Praesent dictum ultricies arcu eu scelerisque. Nulla facilisi.
  </p>
</body>
</html>

Em xem qua thì cũng không khó hiểu cho lắm nhưng có vài chỗ em chưa hiểu sau:

  • Ở chỗ này:
  • ``` .menu .list > li { word-spacing: 0; display: inline-block; } .menu .list li a { display: block; padding: 20px 50px; text-decoration: none; color: #FFFFFF; } ``` Tại sao thẻ `li` chưa set `width` & `height` nhưng khi set padding cho thẻ `a` thì `width` & `height` của thẻ `li` lại tự động dãn ra với kích thước đúng bằng kích thước của thẻ `a` ạ ? (mặc dùng chưa set `width: auto;` và `height: auto;` cho thẻ `li` ?)
  • Ở chỗ này:
  • ```
  • Services
    • Education
    • Open Source
    • Software Solution
  • ``` Tại sao thẻ `ul.sub-menu` nằm trong thẻ `li.dropdown` nhưng khi em inspect element để check thử, thẻ `ul.sub-menu` lại nằm ngoài lẻ `li.dropdown` ?

    Nếu thẻ ul.sub-menu nằm ngoài thẻ li.dropdown thì sao position: absolute; lại có tác dụng được ạ ?
    (e tạm thời sửa display: none; thành display: block; cho dễ quan sát)

  • Ở chỗ này:
  • ```
  • Services
    • Education
    • Open Source
    • Software Solution
  • FAQ
    • License
    • Copyright
  • ``` Tại sao content width của các thẻ `li` con (`education`, `open source`, `license`, ...) khác nhau; padding giống nhau (`padding: 20px 50px;`) nhưng real width của nó lại bằng nhau ạ ? (đáng lẽ chúng phải khác nhau do content width của các thẻ `li` con khác nhau chứ ? hay do ảnh hưởng của thuộc tính `box-sizing` nhỉ ?)

    Và tại sao width của ul.sub-menu ở 2 thẻ li.dropdown lại khác nhau ?
    (Mà cái thẻ li con có nội dung Software solution không biết padding-left và padding-right của nó có đúng 50px không nữa, nhìn thấy khác so với 2 cái thẻ li con trên)

    Đó là những câu hỏi của e, mong các pro giải đáp giúp!
    Em cảm ơn nhiều

    Long Dragon viết 10:17 ngày 01/10/2018

    Sắp tới giao thừa rồi, các bác nào thông cmn cảm giúp e vs ạ
    tình hình là giao thừa vẫn đang code

    Người bị bơ viết 10:26 ngày 01/10/2018

    Tại sao thẻ li chưa set width & height nhưng khi set padding cho thẻ a thì width & height của thẻ li lại tự động dãn ra với kích thước đúng bằng kích thước của thẻ a ạ ? (mặc dùng chưa set width: auto; và height: auto; cho thẻ li ?)

    Đơn giản vì <li> chứa <a> . Khi li chưa đặt width và height thì nó sẽ nhận kích thước của phần tử con ở đây là <a>.

    Tại sao thẻ ul.sub-menu nằm trong thẻ li.dropdown nhưng khi em inspect element để check thử, thẻ ul.sub-menu lại nằm ngoài lẻ li.dropdown ?

    Bạn chắc chứ?

    Tại sao content width của các thẻ li con (education, open source, license, …) khác nhau; padding giống nhau (padding: 20px 50px;) nhưng real width của nó lại bằng nhau ạ ? (đáng lẽ chúng phải khác nhau do content width của các thẻ li con khác nhau chứ ? hay do ảnh hưởng của thuộc tính box-sizing nhỉ ?)

    Nó sẽ lấy thẻ <li> có cái content lớn nhất + padding left + padding right để làm width chung. (Cái này mình chưa test lại, nhưng mình nhớ vậy, lúc trước củng thắc mắc làm thử rồi)

    Và tại sao width của ul.sub-menu ở 2 thẻ li.dropdown lại khác nhau ?

    Như câu trênh, do context width của nó khác với content width của li bên cạnh.
    Chúc mừng năm mới :))

    Sáng Béo viết 10:26 ngày 01/10/2018

    Tại sao thẻ li chưa set width & height nhưng khi set padding cho thẻ a thì width & height của thẻ li lại tự động dãn ra với kích thước đúng bằng kích thước của thẻ a ạ ? (mặc dùng chưa set width: auto; và height: auto; cho thẻ li ?)

    mặc định width height có gía trị là auto rồi bạn.

    Tại sao thẻ ul.sub-menu nằm trong thẻ li.dropdown nhưng khi em inspect element để check thử, thẻ ul.sub-menu lại nằm ngoài lẻ li.dropdown ?

    Nếu thẻ ul.sub-menu nằm ngoài thẻ li.dropdown thì sao position: absolute; lại có tác dụng được ạ ?

    vị trí của nó nằm bên ngoài thôi, do absolute, còn thực chất nó vẫn thuộc thẻ li.

    Tại sao content width của các thẻ li con (education, open source, license, …) khác nhau; padding giống nhau (padding: 20px 50px;) nhưng real width của nó lại bằng nhau ạ ? (đáng lẽ chúng phải khác nhau do content width của các thẻ li con khác nhau chứ ? hay do ảnh hưởng của thuộc tính box-sizing nhỉ ?)

    cái đó là nền của ul, nó giãn ra theo các phần tử con nên nó sẽ có độ dài bằng thằng con dài nhất. còn các li độ dài thế nào mình không thấy bạn di chuột qua để xem mỗi li dài khác nhau không.

    Long Dragon viết 10:30 ngày 01/10/2018

    Đơn giản vì <li> chứa <a> . Khi li chưa đặt width và height thì nó sẽ nhận kích thước của phần tử con ở đây là <a>.

    mặc định width height có gía trị là auto rồi bạn.

    Vậy có nghĩa là khi code CSS, việc để width: auto; hay height: auto; là không cần thiết ạ ?

    Bạn chắc chứ?

    Không, ý em là khi mình rê vào dòng <li class="dropdown"> thì cái ô Services nó màu xanh, còn khi mình rê chuột vào dòng <ul class="sub-menu"> thì nguyên cái khung gồm Education, Open Source với Software Solution nó xanh lên => cái thẻ ul nó nằm ngoài thẻ li đó !

    Nó sẽ lấy thẻ <li> có cái content lớn nhất + padding left + padding right để làm width chung. (Cái này mình chưa test lại, nhưng mình nhớ vậy, lúc trước củng thắc mắc làm thử rồi)

    Ồ, em học nhiều bài CSS rồi mà chưa biết tới cái này Tiện thể, anh có thể cho e vài cái link nói về vấn đề này không ?[quote=“Quan_Tran, post:3, topic:40935”]
    Chúc mừng năm mới :))
    [/quote]

    Nghe ông Trần Đại Quang phát biểu xong là đi ngủ khò khò rồi

    vị trí của nó nằm bên ngoài thôi, do absolute, còn thực chất nó vẫn thuộc thẻ li.

    à, thế có nghĩa là nếu không có position: absolute; thì width của thẻ li.dropdown nó sẽ bao luôn thẻ ul.sub-menu đúng không ạ ?

    cái đó là nền của ul, nó giãn ra theo các phần tử con nên nó sẽ có độ dài bằng thằng con dài nhất. còn các li độ dài thế nào mình không thấy bạn di chuột qua để xem mỗi li dài khác nhau không.

    Size của thẻ li có content License & Copyright là 170 x 58.
    Size của thẻ li có content Education, Open Source & Software Solution là 222 x 58.
    => Cũng giống nhau mà anh nhỉ ?

    HAPPY NEW YEAR !

    Người bị bơ viết 10:29 ngày 01/10/2018

    Vậy có nghĩa là khi code CSS, việc để width: auto; hay height: auto; là không cần thiết ạ ?

    Cái này còn tùy, phụ thuộc vào display (inline, block) và position.

    Không, ý em là khi mình rê vào dòng <li class=“dropdown”> thì cái ô Services nó màu xanh, còn khi mình rê chuột vào dòng <ul class=“sub-menu”> thì nguyên cái khung gồm Education, Open Source với Software Solution nó xanh lên => cái thẻ ul nó nằm ngoài thẻ li đó !

    Thực sự cái này mình đang không hiểu bạn nói gì :), vì nếu thằng <li class="dropdown"> không phải là cha của thằng <ul class="sub-menu"> (chứa), thì khi chúng ta hover vô li.dropdown nó sẽ không cho display:block ở ul.sub-menu. Và ngược lại ul.sub-menu mãi mãi là display:none
    Mâu chốt của dropdown này là thằng li.dropdown chứa thằng ul.sub-menu và khi ta hover vào thằng li.dropdown thì thằng ul.sub-menu nó sẽ chuyển từ display:none -> display:block.

    Long Dragon viết 10:25 ngày 01/10/2018

    Cái này còn tùy, phụ thuộc vào display (inline, block) và position.

    Anh có thể nói rõ vấn đề này hơn nữa được không ?

    Thực sự cái này mình đang không hiểu bạn nói gì :), vì nếu thằng <li class=“dropdown”> không phải là cha của thằng <ul class=“sub-menu”> (chứa), thì khi chúng ta hover vô li.dropdown nó sẽ không cho display:block ở ul.sub-menu. Và ngược lại ul.sub-menu mãi mãi là display:noneMâu chốt của dropdown này là thằng li.dropdown chứa thằng ul.sub-menu và khi ta hover vào thằng li.dropdown thì thằng ul.sub-menu nó sẽ chuyển từ display:none -> display:block.

    Em hiểu ý anh rồi, nhưng anh vẫn chưa hiểu ý em =)))
    Để em đi qua nhà bà con ăn tết xíu rồi về vẽ hình minh họa cho anh cho :))

    Người bị bơ viết 10:25 ngày 01/10/2018

    Ồ, em học nhiều bài CSS rồi mà chưa biết tới cái này Tiện thể, anh có thể cho e vài cái link nói về vấn đề này không ?

    Coi display: list-item

    Người bị bơ viết 10:19 ngày 01/10/2018

    Anh có thể nói rõ vấn đề này hơn nữa được không ?

    Lênh css-tricks đọc tốt nhất
    https://css-tricks.com/almanac/properties/d/display/
    Đọc thêm bài position nữa:
    https://css-tricks.com/almanac/properties/p/position/

    Long Dragon viết 10:21 ngày 01/10/2018

    Coi display: list-item

    Là sao ạ ? Em search rồi mà có thấy gì nói về vấn đề ấy đâu ?

    Người bị bơ viết 10:20 ngày 01/10/2018

    http://hocwebchuan.com/reference/cssSection/example/ex_display.php
    .

    Long Dragon viết 10:20 ngày 01/10/2018

    Em đã xem qua link đó nhưng vẫn không hiểu gì hết anh êiiii :v
    cái chỗ display: list-tem nó có nói gì về vấn đề kia âu ?

    Sáng Béo viết 10:15 ngày 01/10/2018

    Vậy có nghĩa là khi code CSS, việc để width: auto; hay height: auto; là không cần thiết ạ ?

    còn tuỳ, có thể phải đặt nếu muốn ghi đè lại thuộc tính này đã được set ở css khác.

    à, thế có nghĩa là nếu không có position: absolute; thì width của thẻ li.dropdown nó sẽ bao luôn thẻ ul.sub-menu đúng không ạ ?

    có thể nói thế. bạn có thể thử.

    Size của thẻ li có content License & Copyright là 170 x 58.Size của thẻ li có content Education, Open Source & Software Solution là 222 x 58.=> Cũng giống nhau mà anh nhỉ ?

    nếu không bị ghi đè thì mặc định li là thẻ có thuộc tính display list-item, thuộc tính này cũng giống display block là chiếm 100% width của parent. vậy nên các li sẽ có width bằng nhau và bằng thằng li dài nhất trong cùng ul.

    Hung Pham viết 10:28 ngày 01/10/2018

    Chỉ thế này là xong thôi mà

    See the Pen ygvQrJ by Hung Pham (@machao112) on CodePen.

    Vũ Thanh viết 10:29 ngày 01/10/2018

    Theo mình đoạn code này cực kỳ đơn giản, dễ hiểu
    Pế/ết: Nhúng CSS theo kiểu External Style

    • File HTML
    <!DOCTYPE html>
    <html>
    	<head>
    		<title>Menu ngang Dropdown</title>
    		<meta charset="utf-8" />
    		<meta name="author" content="Thanh" />
    		<link rel="stylesheet" href="style.css" />
    	</head>
    	<body>
    		<div id="menu">
    		  <ul>
    		    <li><a href="#">Home</a></li>
    		    <li><a href="#">About</a></li>
    		    <li>
    		      <a href="#">Services</a>
    		      <ul class="sub-menu">
    		        <li><a href="#">Education</a></li>
    		        <li><a href="#">Open Source</a></li>
    		        <li><a href="#">Software Solution</a></li>
    		      </ul>
    		    </li>
    		    <li><a href="#">FAQ</a></li>
    		    <li><a href="#">Contact</a></li>
    		  </ul>
    		</div>
    	</body>
    </html>
    
    • File CSS
    * {
      padding: 0;
      margin: 0;
    }
    
    body {
      font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
      color: #333;
    }
    
    #menu ul {
      background-color: #000;
      text-align: center;
      list-style-type: none;
    }
    
    #menu ul li {
      display: inline-table;
      width: 150px;
      height: 60px;
      line-height: 60px;
      position: relative;
    }
    
    #menu ul li a {
      display: block;
      text-decoration: none;
      color: #f1f1f1;
    }
    
    #menu ul li:hover {
      background: #151515;
      transition: all 0.5s;
      -moz-transition: all 0.5s;
      -webkit-transition: all 0.5s;
    }
    
    #menu ul li > .sub-menu {
      display: none;
    }
    
    #menu ul li:hover .sub-menu {
      display: block;
      position: absolute;
    }
    
    Bài liên quan
    0