Responsive dropdown navbar - navbar

I am doing a school project in which I'm not allowed to use Javascript or Bootstrap, and I cannot find a way to make a dropdown menu when the site is opened in smaller screens. Most guides and videos show using Bootstrap or JS and it has gotten me all confused, is it possible to do with just HTML and CSS?. Can anyone give me some quick tips or alternatives? Thank you beforehand!

Answer below using HTML and CSS only.
If my answer works, please check it as final answer and upvote it so other people with same problem will get help too. Cheers
<div class="dropdown">
<button class="dropbtn">Dropdown</button>
<div class="dropdown-content">
Link 1
Link 2
Link 3
</div>
</div>
<style>
/* Style The Dropdown Button */
.dropbtn {
cursor: pointer;
}
/* The container <div> - needed to position the dropdown content */
.dropdown {
position: relative;
display: inline-block;
}
/* Dropdown Content (Hidden by Default) */
.dropdown-content {
display: none;
position: absolute;
z-index: 1;
}
/* Links inside the dropdown */
.dropdown-content a {
color: black;
padding: 12px;
text-decoration: none;
display: block;
}
/* Show the dropdown menu on hover */
.dropdown:hover .dropdown-content {
display: block;
}
</style>

Related

CSS-only dropdown menu works fine but not in Edge

I am working on a CSS-only dropdown menu. This is the code I am using now:
.show
{ display: none;
}
.hide:focus + .show
{display: block;
}
.hide:focus
{display: none;
}
#ddm
{display: none;
}
.hide:focus ~ #ddm
{display: block;
}
<body>
menumenu
<div id="ddm">items</div>
</body>
It works heartily in all browsers except Microsoft Edge. That browser only shows the menu for a fraction of a second. :( Does anyone possibly know what is happening here? And how I can fix this? I appreciate all the help. Thank you very much!
Kind regards,
George.
Updated Answer: As per comments, without using JavaScript or a checkbox technique and using the :focus pseudo class, you could wrap the menus in a button and use that as the initial focus trigger.
/* Menu styling for demo, change as needed */
#menu {
cursor: pointer;
padding: 0px;
border: 0;
background: none;
}
/* Hidden initially */
#ddm,
#hide {
display: none;
}
/* Prevent the 'show' element from triggering focus */
#show {
pointer-events: none;
}
/* Show elements as needed */
#menu:focus~#ddm,
#menu:focus #hide,
#menu:not(:focus) #show,
#hide:focus #show {
display: block;
}
/* Hide elements as needed */
#menu:focus #show,
#menu:not(:focus)~#hide,
#hide:focus #hide {
display: none;
}
<body>
<!-- New button element to wrap around the two menus -->
<button id="menu">
<!-- Numbers in text added just to demonstrate the difference -->
menu1
menu2
</button>
<div id="ddm">items</div>
</body>
Original Answer: Perhaps a simpler approach would fit your needs (unless you have a specific reason to use two menus that are hidden and shown). Just have one menu that is always shown, and toggle the items depending on its focus:
#ddm {
display: none;
}
.menu:focus~#ddm {
display: block;
}
<body>
menu
<div id="ddm">items</div>
</body>
I would still be using javascript or the checkbox method as they are more robust, but the following could work.
Use some creative positioning and the :target pseudo class, which selects the element referenced by href=#someId and then sibling selectors. Then the id for the burger menu is added to the show link href which is also better semantics. The hide/show buttons will need to be added after the menu element then repositioned with position:absolute.
/*Position everything relative to nav*/
nav {
position: relative;
padding-top: 1.25em;
}
/*Position our show/hide elements*/
.show,.hide {
position: absolute;
top: 0;
}
/*Hide burger and button */
#ddm, #ddm:not(:target) ~ .hide {
display: none;
}
/*Show Burger when show clicked*/
#ddm:target {
display: block;
}
/*HIde Burger when not show clicked*/
#ddm:target~.show {
display: none;
}
<body>
<!-- Nav Used For Positioning -->
<nav>
<div id="ddm">Burger</div>
Show Burger
Hide Burger
</nav>
</body>

Center responsive navigation bar

I am following a guide from w3schools to build a responsive top navigation bar for my site: How TO - Responsive Top Navigation
However, I would like the navigation items to be centered on the page, not aligned to the left or right. w3schools even has a second tutorial on a center navigation element link, but as soon as I try to use this code for several navigation elements, they either are all within each other or stack on top of each other!
Even more to my dismay, there has been a question about this exact problem before (here), but it seems the code of the example has been changed a lot in the meanwhile so that the answer is no longer applicable. :(
To center the top navigation in the link you've provided, you would add the following to .topnav:
.topnav {
…
display: flex;
justify-content: center;
}
To address the mobile menu (and not center it), add the following to your #media query:
#media screen and (max-width: 600px) {
…
.topnav { display: block; }
}
Before
After
One way is to wrap the links inside a div (say, a div with class nav-links), and then applying to the div:
.nav-links {
width: fit-content; /* 'margin: auto' alone does not work if the div takes full width */
margin: auto;
}
Below is a demo based on the tutorial you linked:
.nav-links {
width: fit-content;
margin:auto;
}
/*////////////// W3Schools CSS code //////////////*/
/* Add a black background color to the top navigation */
.topnav {
background-color: #333;
overflow: hidden;
}
/* Style the links inside the navigation bar */
.topnav a {
float: left;
display: block;
color: #f2f2f2;
text-align: center;
padding: 14px 16px;
text-decoration: none;
font-size: 17px;
}
/* Change the color of links on hover */
.topnav a:hover {
background-color: #ddd;
color: black;
}
/* Add an active class to highlight the current page */
.topnav a.active {
background-color: #4CAF50;
color: white;
}
/* Hide the link that should open and close the topnav on small screens */
.topnav .icon {
display: none;
}
<!-- Load an icon library to show a hamburger menu (bars) on small screens -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<div class="topnav" id="myTopnav">
<div class="nav-links">
Home
News
Contact
About
<a href="javascript:void(0);" class="icon" onclick="myFunction()">
<i class="fa fa-bars"></i>
</a>
</div>
</div>

Using css/html dropdown as Mediawiki template

I am trying to use this dropdown as a Mediawiki template and allow for Mediawiki parameters in the URL creation (I.e. {{PAGENAME}}). Apparently, this type of html elements is not parsed. Trying $wgRawHtml = true; resulted in the template being displayed, but, apart from being a security risk, there was no way to have parsable elements. I did find this template but I could not figure out how do adapt it to work with the styling of the dropdown in question.
In the page MediaWiki:Common.css (or MediaWiki:Skinname.css, if you only want it for a certain skin), add your desired CSS:
/* Dropdown Button */
.dropbtn {
background-color: #4CAF50;
color: white;
padding: 16px;
font-size: 16px;
border: none;
}
/* The container <div> - needed to position the dropdown content */
.dropdown {
position: relative;
display: inline-block;
}
/* Dropdown Content (Hidden by Default) */
.dropdown-content {
display: none;
position: absolute;
background-color: #f1f1f1;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
/* Links inside the dropdown */
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
/* Change color of dropdown links on hover */
.dropdown-content a:hover {background-color: #ddd;}
/* Show the dropdown menu on hover */
.dropdown:hover .dropdown-content {display: block;}
/* Change the background color of the dropdown button when the dropdown content is shown */
.dropdown:hover .dropbtn {background-color: #3e8e41;}
If everything in the template is going to be an internal link, make this your template:
<div class="dropdown">
<div class="dropbtn">{{{title|Dropdown}}}</div>
<div class="dropdown-content"><!--
-->{{#if:{{{1|}}}|[[{{{1}}}]]}}<!--
-->{{#if:{{{2|}}}|[[{{{2}}}]]}}<!--
-->{{#if:{{{3|}}}|[[{{{3}}}]]}}<!--
-->{{#if:{{{4|}}}|[[{{{4}}}]]}}<!--
-->{{#if:{{{5|}}}|[[{{{5}}}]]}}<!--
</div>
</div>
And then invoke it like this:
{{dropdown|Foo|Bar|Baz}}
And it will make a dropdown with links to the pages Foo, Bar, and Baz on your wiki.
If you have to support external links or plaintext, use this instead:
<div class="dropdown">
<div class="dropbtn">{{{title|Dropdown}}}</div>
<div class="dropdown-content plainlinks"><!--
-->{{#if:{{{1|}}}|<span>{{{1}}}</span>}}<!--
-->{{#if:{{{2|}}}|<span>{{{2}}}</span>}}<!--
-->{{#if:{{{3|}}}|<span>{{{3}}}</span>}}<!--
-->{{#if:{{{4|}}}|<span>{{{4}}}</span>}}<!--
-->{{#if:{{{5|}}}|<span>{{{5}}}</span>}}<!--
--></div>
</div>
Change the as in the CSS to spans, and add a rule to make sure they are black instead of blue:
/* Links inside the dropdown */
.dropdown-content span {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
/* Change color of dropdown links on hover */
.dropdown-content span:hover {background-color: #ddd;}
.dropdown-content a, .dropdown-content a:hover{
color: black;
text-decoration: none;
}
And then, you can invoke it like
{{dropdown|[[Foo]]|[https://www.google.com/ Google]|Plain text}}
and it has a link to the page Foo, a link to Google, and a plain-text menu item.
Note: If a parameter contains an equals sign (=), you need to specify all the parameter names, like this:
{{dropdown|1=[https://duckduckgo.com/?q=foo&ia=web Search for Foo]|2=Bar}}
See also: Passing an equal sign ('=') to a parameter in a MediaWiki template
So I tried to use this, and I'm having an issue where the rest of the page content that is after the dropdown, is in the dropdown itself. IT doesn't look like any of the parameters aren't closed, so I'm not sure why it's doing that. Using MW1.32

How to stop dropdown list appearing on top of list item

So I'm trying to configure a simple dropdown list from a list item but I can't for the life of me figure out why it wont stop covering the list item when I hover over it. Here's the html:
<div class="dropdown" style="float:right">
<li><a class="active dropbtn" href="">Profile</a></li>
<div class="dropdown-content">
Link 1
Link 2
<span class="glyphicon glyphicon-log-out"></span> Logout</a>
</div>
</div>
And the css to style this is:
tr:hover {background-color: #f5f5f5}
th, td {
padding: 15px;
text-align: left;
}
/* The container <div> - needed to position the dropdown content */
.dropdown {
position: relative;
}
/* Dropdown Content (Hidden by Default) */
.dropdown-content {
display: none;
position: absolute;
background-color: #f9f9f9;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 10;
}
/* Links inside the dropdown */
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
/* Change color of dropdown links on hover */
.dropdown-content a:hover {background-color: #f1f1f1}
/* Show the dropdown menu on hover */
.dropdown:hover .dropdown-content {
display: block;
}
/* Change the background color of the dropdown button when the dropdown content is shown */
.dropdown:hover .dropbtn {
background-color: #3e8e41;
In addition to this, despite changing the z-index of the dropdown elements I can't get the menu to appear outside of the menu where the parent list is located
All help is appreciated
Well, the code gave me a few errors.... Please look at this JSfiddle and tell me if it's working now? Also please, tell me what you want because I'm a bit confused..
https://jsfiddle.net/xxsycmyj/
<div class="dropdown" style="float:left">
<li><a class="active dropbtn" href="">Profile</a></li>
<div class="dropdown-content">
Link 1
Link 2
<span class="glyphicon glyphicon-log-out"></span> Logout
</div>
The CSS looked fine to me.

How does changing the display attribute in the styling of an element hide/show it?

I'm following this tutorial on how to create a CSS dropdown menu. Currently the method stated does not use any JavaScript (only HTML and CSS). Here is the method suggested, excluding the color/background color/font/etc.
.dropdown {
position: relative;
display: inline-block;
}
.dropdown-content {
display: none;
position: absolute;
}
.dropdown-content a {
display: block;
}
.dropdown:hover .dropdown-content {
display: block;
}
<div class="dropdown">
<button class="dropbtn">Dropdown</button>
<div class="dropdown-content">
Link 1
Link 2
Link 3
</div>
</div>
As you can see, the Dropdown button appears, and when one hovers over it, the list items are shown. The only styling applied when an element is hovered over is
.dropdown:hover .dropdown-content {
display: block;
}
How does this work? (the w3schools tutorial did not describe the reasoning behind the display styling)
When I ran the above snippet, I was expecting the list items to be shown inline and then, when the button is hovered over, to be shown as a block under the button (thus I was expecting the list items to never be hidden). What is making these list items hidden by default?
Furthermore, if I am applying the display: block styling on the div element (the one with the class dropdown), then how come when I hover over the empty space still physically under the button, however to the right of the list text, the display: block styling is undone (and the list items vanish)? I would expect the div element to take up an area in the shape of a rectangle (where even hovering over the white part of the rectangle would trigger :hover). *
* I may need to clarify this entire part of my question, please say so if I need to.
The .dropdown-content is hidden by default:
.dropdown-content {
display: none;
}
The later rule overrides that and shows the content when the pointer hovers over the parent .dropdown:
.dropdown:hover .dropdown-content {
display: block;
}
This rule applies to any .dropdown-content within a .dropdown that is in the hover state.
To answer the second question, it's because of the position: absolute that the white-space next to the child items don't maintain the hover state. See the snippet below, which includes outlines to show the boundaries of each element. As long as the pointer is within the blue (parent) box or the red (child) box, the hover state is maintained.
.dropdown {
position: relative;
display: inline-block;
outline: solid 1px blue;
}
.dropdown-content {
display: none;
position: absolute;
outline: solid 1px red;
}
.dropdown-content a {
display: block;
background: yellow;
}
.dropdown:hover .dropdown-content {
display: block;
}
<div class="dropdown">
<button class="dropbtn">Dropdown</button>
<div class="dropdown-content">
Link 1
Link 2
Link 3
</div>
</div>