I've got myself all in a mess. When each of the "..." within the span is clicked, I would like the myDropdown div containing "Report" to be shown next to the span.
Then I would like for when the corresponding Report is clicked to return the id of the "elementid" class in this case either 1 or 2 but I wasn't sure what to put in the reportFunction
<html>
<style>
.dropbtn {
background-color: white;
color: black;
padding: 2px;
font-size: 30px;
border: none;
cursor: pointer;
font-weight: bold;
}
.dropdown {
position: relative;
display: inline-block;
}
.dropdown-content {
display: none;
background-color: #f9f9f9;
min-width: 160px;
font-size:10px;
overflow: auto;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
border: 1px solid lightgrey;
z-index: 1;
float: left;
}
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.dropdown a:hover {background-color: #f1f1f1;cursor:pointer;}
.show {display:block;}
</style>
<span class="dropdown">
<button onclick="myFunction()" class="dropbtn">...</button>
<div id="myDropdown" class="dropdown-content">
<a class="elementid" id="1">Report</a>
</div>
</span>
<p>
<span class="dropdown">
<button onclick="myFunction()" class="dropbtn">...</button>
<div id="myDropdown" class="dropdown-content">
<a class="elementid" id="2">Report</a>
</div>
</span>
<script>
function myFunction() {
document.getElementById("myDropdown").classList.toggle("show");
}
window.onclick = function(event) {
if (!event.target.matches('.dropbtn')) {
var dropdowns = document.getElementsByClassName("dropdown-content");
var i;
var id = document.getElementsByID("id");
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
}
}
}
}
function reportFunction() {
}
</script>
</html>
Something like this should get you the id you want. It goes up to the containing span with parent() and then gets the element with class elementId within.
function reportFunction() {
var id = $(this).parent().find('.elementid');
... //whatever you need to do
}
Your code has other problems though. You have two div elements with the same id myDropdown. Your current code with getElementById will always get the first one. You need to either specify a class and no id on them, and get the right one in the same way as above, or to use one div that you remove and attach to the correct span as needed.
Related
Hello all I have a problem when I use two dropdowns, when you click on one, both are opened, below is my code:
function myFunction() {
document.getElementById("myDropdown").classList.toggle("show");
}
window.onclick = function (event) {
if (!event.target.matches('.dropbtn')) {
var dropdowns = document.getElementsByClassName("dropdown-content");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
}
}
}
}
function newFunction() {
document.getElementById("myDropdown1").classList.toggle("show");
}
window.onclick = function (event) {
if (!event.target.matches('.dropbtn')) {
var dropdowns = document.getElementsByClassName("dropdown-content");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
}
}
}
}
.dropbtn {
background-color: #ffffff;
color: #252930;
font-size: 18px;
border: none;
cursor: pointer;
}
.dropdown {
position: relative;
display: inline-block;
}
.dropbtn-selected {
background-color: #ec292d;
color: #fff!important
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f1f1f1;
min-width: max-content;
overflow: auto;
margin-top: 15px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
z-index: 969999;
}
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.dropdown a:hover {
background-color: #ddd;
}
.show {
display: block;
}
.dropbtn>i {
pointer-events: none;
}
<li class="dropdown desktopNav">
<button onclick="myFunction()" class="dropbtn">Test <i
class="fas fa-chevron-down"></i></button>
<div id="myDropdown" class="dropdown-content">
Lorem1
Lorem 2
Lorem 3
</div>
</li>
<li class="dropdown desktopNav">
<button onclick="newFunction()" class="dropbtn">Second <i
class="fas fa-chevron-down"></i></button>
<div id="myDropdown1" class="dropdown-content">
Lorem 4
Lorem 5
Lorem 6
</div>
</li>
Is there a way to make this code more flexible? I want to achieve, when the user clicks on the dropdown that dropdown should be only opened,.
Can somebody try to help me with this? What is the best way to achieve this?
To have only one dropdown visible at a time you need to hide all others. The simple way to achieve this is to group the element structures by classname based on their behaviour, as opposed to giving each block its own incremental id. The latter approach leads to bloated duplicate code which becomes harder to maintain.
To fix this remove the id and give all the elements in the repeated blocks the same class. From there you can use DOM traversal to relate the elements to each other, hiding and displaying as necessary.
let dropdownContents = document.querySelectorAll('.dropdown-content');
// display the dropdown relevant to the clicked button
document.querySelectorAll('.dropbtn').forEach(btn => {
btn.addEventListener('click', e => {
let targetContent = e.target.parentNode.querySelector(".dropdown-content");
targetContent.classList.toggle("show");
dropdownContents.forEach(el => el !== targetContent && el.classList.remove('show'));
});
});
// hide all dropdowns when the document is clicked
document.addEventListener('click', e => {
if (!e.target.matches('.dropbtn'))
dropdownContents.forEach(el => el.classList.remove('show'));
})
.dropbtn {
background-color: #ffffff;
color: #252930;
font-size: 18px;
border: none;
cursor: pointer;
}
.dropdown {
position: relative;
display: inline-block;
}
.dropbtn-selected {
background-color: #ec292d;
color: #fff!important
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f1f1f1;
min-width: max-content;
overflow: auto;
margin-top: 15px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
z-index: 969999;
}
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.dropdown a:hover {
background-color: #ddd;
}
.show {
display: block;
}
.dropbtn>i {
pointer-events: none;
}
<ul>
<li class="dropdown desktopNav">
<button class="dropbtn">Test <i class="fas fa-chevron-down"></i></button>
<div class="dropdown-content">
Lorem1
Lorem 2
Lorem 3
</div>
</li>
<li class="dropdown desktopNav">
<button class="dropbtn">Second <i class="fas fa-chevron-down"></i></button>
<div class="dropdown-content">
Lorem 4
Lorem 5
Lorem 6
</div>
</li>
</ul>
Note the use of addEventListener over the outdated onX properties, and also the click handler which hides the dropdowns being attached to the document instead of the window.
There is no seperate 'close' event, so when clicking the second, there's no reason why the first should close.
You could have a variable that is set when a dropdown is to be shown. When clicking the second dropdown, the function would check if the variable is set, and if so, toggle that one off before toggling the correct one on. Eg:
let dropdownShown = null;
function onClick(e) {
if (dropdownShown !== e.target) {
dropdownShown.classList.toggle("show");
}
e.target.classList.toggle("show");
dropdownShown = e.target;
}
First of all, I am new with javascript, html, and CSS so bear with me. I have looked everywhere for the answer to my question but I can't find anything that works for my specific code.
I am trying to create a webpage that has multiple dropdown menus and that each one opens when the user clicks on it. I am able to do this but an issue occurs. If I open a dropdown menu and then click on another dropdown menu, the first menu remains open. I want the first menu to close when I open a new one.
Here is a section of my html code with 2 of the dropdown menus:
<table class="prodMenu">
<tr><td>
<div class="dropdown2">
<button onclick="myFunction('m1')" class="dropbtn2">SPCGuidance</button>
<div id="m1" class="dropdown2-content">
[PR]:4-hr Calibrated Tornado Probability
[PR]:4-hr Calibrated Hail Probability
</div>
</div>
</td>
<td>
<div class="dropdown2">
<button onclick="myFunction('m2')" class="dropbtn2">Reflectivity</button>
<div id="m2" class="dropdown2-content">
[SP]:3-hr 1-km Reflectivity >=40 dBZ
[NPRS]:3-hr 1-km Reflectivity >=40 dBZ
</div>
</div>
</td>
Next is the part of the .js script that interacts with these dropdown menus. I do have a function that closes the open menus if you click somewhere in the window. However, I'm not sure how to make a function that closes the first dropdown menu when another dropdown menu is opened.
// When the user clicks on the button, toggle between hiding and showing the dropdown content.
function myFunction(id) {
document.getElementById(id).classList.toggle("show");
}
// Close the dropdown if the user clicks in window.
window.onclick = function(event) {
if (!event.target.matches('.dropbtn2')) {
var dropdowns = document.getElementsByClassName("dropdown2-content");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
}
}
}
}
And finally here is the part of the CSS script that controls the dropdown menus:
/* dropdown2 is for the rest of the dropdown menus. */
.dropbtn2 {
background-color: #444444;
color: #FFFFFF;
margin: 0 1px 0 0;
padding: 4px 3px;
width: auto;
font: bold 10px arial;
cursor: pointer;
text-align: center;
white-space: nowrap;
text-decoration: none;
border: none;
}
.dropbtn2:hover, .dropbtn2:focus {
background-color: #000066;
border: none;
}
.dropdown2 {
position: relative;
display: inline-block;
z-index: 30;
.dropdown2-content {
display: none;
position: absolute;
padding: 0px;
width: auto;
min-width: 160px;
white-space: nowrap;
background: #DDDDDD;
overflow: auto;
z-index: 1;
border-style: solid;
border-width: 1px;
border-color: #000000;
}
.dropdown2-content a {
color: #000000;
padding: 2px 3px;
font: 10px arial;
display: block;
}
.dropdown2 a:hover {
background: #000066;
color: #FFF;
border: none;
text-decoration: none;
}
.show {
display:block;
}
Any help would be greatly appreciated. Thanks.
EDIT:
I got it.
For the Javascript part, this successfully closes the current dropdown menu when you click on another, click outside in the window, or click again on the same menu's header.
function myFunction(id) {
var dropdowns = document.getElementsByCLassName("dropdown2-content");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if ( dropdowns[i] != document.getElementById(id) ) {
openDropdown.classList.remove('show');
}
}
document.getElementById(id).classList.toggle("show");
}
// Close the dropdown if the user clicks in window.
window.onclick = function(event) {
if (!event.target.matches('.dropbtn2')) {
var dropdowns = document.getElementsByClassName("dropdown2- content");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
}
}
}
}
You can just close all dropdowns before opening the one that was clicked
function myFunction(id) {
var dropdowns = document.getElementsByClassName("dropdown2-content");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
openDropdown.classList.remove('show');
}
document.getElementById(id).classList.toggle("show");
}
If you can include jQuery and use it, this will work:
$(document).ready(function(){
$(document).on('click','.dropbtn2',function(){
$('.dropbtn2').not(this).next().removeClass('show');
$(this).next().toggleClass('show');
});
$(document).on('click',function(e){
if(!$(e.target).closest('.dropbtn2').length)
$('.dropbtn2').next().removeClass('show');
});
});
/* dropdown2 is for the rest of the dropdown menus. */
.dropbtn2 {
background-color: #444444;
color: #FFFFFF;
margin: 0 1px 0 0;
padding: 4px 3px;
width: auto;
font: bold 10px arial;
cursor: pointer;
text-align: center;
white-space: nowrap;
text-decoration: none;
border: none;
}
.dropbtn2:hover, .dropbtn2:focus {
background-color: #000066;
border: none;
}
.dropdown2 {
position: relative;
display: inline-block;
z-index: 30;
}
.dropdown2-content {
display: none;
position: absolute;
padding: 0px;
width: auto;
min-width: 160px;
white-space: nowrap;
background: #DDDDDD;
overflow: auto;
z-index: 1;
border-style: solid;
border-width: 1px;
border-color: #000000;
}
.dropdown2-content a {
color: #000000;
padding: 2px 3px;
font: 10px arial;
display: block;
}
.dropdown2 a:hover {
background: #000066;
color: #FFF;
border: none;
text-decoration: none;
}
.show {
display:block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<table class="prodMenu">
<tr><td>
<div class="dropdown2">
<button class="dropbtn2">SPCGuidance</button>
<div id="m1" class="dropdown2-content">
[PR]:4-hr Calibrated Tornado Probability
[PR]:4-hr Calibrated Hail Probability
</div>
</div>
</td>
<td>
<div class="dropdown2">
<button class="dropbtn2">Reflectivity</button>
<div id="m2" class="dropdown2-content">
[SP]:3-hr 1-km Reflectivity >=40 dBZ
[NPRS]:3-hr 1-km Reflectivity >=40 dBZ
</div>
</div>
</td>
I'd say the best solution is to use Bootstrap, which can handle these situations right out of the box: see how it works http://getbootstrap.com/components/#btn-dropdowns
If you for some reason cannot use Bootstrap and can use jQuery, that would be quite easy too. When clicking the button, you would hide all the dropdowns and then show just the adjacent one. It would go something like this:
$('.dropbtn2').click(function(){
$('.dropdown2-content).hide(); // hide all the dropdowns
$(this).next().show(); // show the next sibling
});
If you can use neither Bootstrap nor jQuery, just copy the code you have in the windows.onclick part before showing the element in myFunction, as Funk Doc said.
I am using a couple of drop down boxes with the below scripts, everything works except for clicking outside of the window, which will only work on the last button, I know there is a way to seperate the window.onclick functions but I'm not sure how, have tried a few things but can't find much information on this.
Any help would be much appreciated!
<script>
/* When the user clicks on the button,
toggle between hiding and showing the dropdown content */
function myFunction20() {
document.getElementById("myDropdown20").classList.toggle("show");
}
// Close the dropdown if the user clicks outside of it
window.onclick = function(event20) {
if (!event.target.matches('.dropbtn20')) {
var dropdowns20 = document.getElementsByClassName("dropdown-content20");
var i;
for (i = 0; i < dropdowns20.length; i++) {
var openDropdown20 = dropdowns20[i];
if (openDropdown20.classList.contains('show')) {
openDropdown20.classList.remove('show');
}
}
}
}
</script>
<script>
/* When the user clicks on the button,
toggle between hiding and showing the dropdown content */
function myFunction21() {
document.getElementById("myDropdown21").classList.toggle("show");
}
// Close the dropdown if the user clicks outside of it
window.onclick = function(event21) {
if (!event.target.matches('.dropbtn21')) {
var dropdowns21 = document.getElementsByClassName("dropdown-content21");
var i;
for (i = 0; i < dropdowns21.length; i++) {
var openDropdown21 = dropdowns21[i];
if (openDropdown21.classList.contains('show')) {
openDropdown21.classList.remove('show');
}
}
}
}
</script>
the one on the right will close when clicking outside the button and dropdown but the one on the left will not.. https://jsfiddle.net/c94gLhqm/
The result of the comments chat above. Adding here for clarity. Introduced onblur in the HTML
/* When the user clicks on the button,
toggle between hiding and showing the dropdown content */
function myFunction() {
document.getElementById("myDropdown").classList.toggle("show");
}
function myFunction2() {
document.getElementById("myDropdown2").classList.toggle("show");
}
.dropbtn {
background-color: #85c445;
color: white;
padding: 16px;
font-size: 16px;
border: none;
cursor: pointer;
width: 170px;
}
.dropbtn:hover, .dropbtn:focus {
background-color: #3e8e41;
}
.dropdown {
position: relative;
display: inline-block;
z-index: 6
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f9f9f9;
min-width: 160px;
overflow: auto;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
}
.dropdown-content a {
color: black;
font-size: 16px;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.dropdown a:hover {background-color: #f1f1f1}
.show {display:block;}
.dropbtn2 {
background-color: #85c445;
color: white;
padding: 16px;
font-size: 16px;
border: none;
cursor: pointer;
width: 170px;
}
.dropbtn2:hover, .dropbtn2:focus {
background-color: #3e8e41;
}
.dropdown2 {
position: relative;
display: inline-block;
z-index: 6
}
.dropdown-content2 {
display: none;
position: absolute;
background-color: #f9f9f9;
min-width: 160px;
overflow: auto;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
}
.dropdown-content2 a {
color: black;
font-size: 16px;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.dropdown2 a:hover {background-color: #f1f1f1}
.show {display:block;}
<div class="dropdown">
<button onblur="myFunction()" onclick="myFunction()" class="dropbtn">Example</button>
<div id="myDropdown" class="dropdown-content">
1
2
3
4
5
</div>
</div>
<div class="dropdown2">
<button onblur="myFunction2()" onclick="myFunction2()" class="dropbtn2">Example</button>
<div id="myDropdown2" class="dropdown-content2">
1
2
3
4
5
</div>
</div>
I think change your once window onclick method
<script>
/* When the user clicks on the button,
toggle between hiding and showing the dropdown content */
function myFunction20() {
document.getElementById("myDropdown20").classList.toggle("show");
}
/* When the user clicks on the button,
toggle between hiding and showing the dropdown content */
function myFunction21() {
document.getElementById("myDropdown21").classList.toggle("show");
}
// Close the dropdown if the user clicks outside of it
window.onclick = function(event20) {
if (!event.target.matches('.dropbtn20')) {
var dropdowns20 = document.getElementsByClassName("dropdown-content20");
var i;
for (i = 0; i < dropdowns20.length; i++) {
var openDropdown20 = dropdowns20[i];
if (openDropdown20.classList.contains('show')) {
openDropdown20.classList.remove('show');
}
}
} else if (!event.target.matches('.dropbtn21')) {
var dropdowns21 = document.getElementsByClassName("dropdown-content21");
var i;
for (i = 0; i < dropdowns21.length; i++) {
var openDropdown21 = dropdowns21[i];
if (openDropdown21.classList.contains('show')) {
openDropdown21.classList.remove('show');
}
}
}
}
</script>
i am trying to make a clickable menu, and trying to make it toggle using javascript and css, but I want to make the each also to have sub-menus also toggle, and I trying to do it mainly with javascript, how can I make it?
Here is my code:
HTML:
<div class="dropdown">
<button onclick="myFunction()" class="dropbtn">|||</button>
<div id="myDropdown" class="dropdown-content">
Link 1
Link 2
<div class="child-dropdown">
Sublink 1
Sublink 1
Sublink 1
</div>
Link 3
<div class="child-dropdown">
Sublink 1
Sublink 1
Sublink 1
</div>
</div>
</div>
Javascript:
<script>
function myFunction() {
document.getElementById("myDropdown").classList.toggle("show");
}
window.onclick = function(event) {
if (!event.target.matches('.dropbtn')) {
var dropdowns = document.getElementsByClassName("dropdown-content");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
}
}
}
}
</script>
css
.dropbtn {
background-color: #cc0000;
color: white;
padding: 16px;
font-size: 16px;
border: none;
cursor: pointer;
position:relative;
}
.dropbtn:hover, .dropbtn:focus {
background-color: #e6e6e6;
}
.dropdown {
position: relative;
display: inline-block;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #e6e6e6;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
}
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.dropdown-content a:hover {background-color: #cc0000}
.show {display:block;}
With the given markup, javascript would not be even necessary for links inside #myDropdown: you could just use :focus pseudoclass like so
#myDropdown a:focus + div {
display: block;
}
Of course this works as long as your link is focused: if you want to be able to have something else focused (or open many submenus) you could use a bit of javascript like
[].forEach.call(document.querySelectorAll('#myDropdown > a'), function(l) {
l.addEventListener('click', function() {
l.classList.toggle('open');
}, false);
});
or with event delegation on #myDropdown
document.getElementById('myDropdown').addEventListener('click', function(evt) {
var target = evt.target;
if (target.nodeName.toLowerCase() === 'a') {
target.classList.toggle('open');
}
}, false);
and this CSS
#myDropdown div { display: none; }
#myDropdown a.open + div { display: block; }
Codepen Demo
I am trying to create a disappearing drop down menu that disappears into the top of the page, and you can only see the word 'open'. This opens the the menu, the word open changes to the word close which when clicked makes the menu disappear again. Help would be much appricated.
<html>
<head>
<title>dropdown</title>
<link rel="stylesheet" type="text/css" href="dropdown_css.css">
<script type = "text/javascript">
function navagate(menu) {
var panel = document.getElementById(menu),maxh = "-362px", navg = document.getElementById('navag');
if (panel.style.marginTop == maxh){
panel.style.marginTop = "0px";
navag.innerHTML = "Close";
}
else {
panel.style.marginTop = maxh;
navag.innerHTML = "Open";
}
}
window.onload = function(){panel.style.marginTop = "-362px";}
</script>
<body>
<div id = "panel">
<ul>
<li>CIT</li>
<li>Blackboard</li>
<li>Mcomms</li>
<li>Tables</li>
<li>Exams</li>
</ul>
<div id ="sections_button">
<a onclick = "navigate ('panel')" id = "navag">Open</a>
</div>
</div>
</body>
</body>
</html>
#panel {
width : 160px;
height: 130px;
background-color: gray;
margin-left: 30px;
margin-top:20px;
}
#panel li {
list-style-type: none;
}
Here, I've made a JS fiddle that may help you out: http://jsfiddle.net/942z0nhh/ I did not play around with the styling at all.
A few things I noticed:
You're making some mistakes that I think you wouldn't make if you indented properly. Take a look here, where you closed your body twice:
<a onclick = "navigate ('panel')" id = "navag">Open</a>
</div>
</div>
</body>
</body>
Second, you have some spelling mistakes:
<a onclick = "navigate ('panel')" id = "navag">Open</a>
vs
function navagate(menu) {
You can see there that your function would never be called because of it.
Lastly, your 'open' and 'close' a here:
<a onclick = "navigate ('panel')" id = "navag">Open</a>
Was within the div your function was overwriting. The function would change it to 'close'- but then it wouldn't be visible to the user anyway! I moved it above, which I hope makes sense.
Please let me know if you have any other questions, or if I misunderstood.
You could also do it only with CSS. It's the "css checkbox hack". I'm having it not like you want it but it is pretty close. Changing the text from open to close should be also possible.
At the moment, I don't know how to move the open/close label below the ul list.
*, html {
padding: 0px;
font-family: sans-serif;
}
/* Checkbox Hack */
input[type=checkbox] {
position: absolute;
display: none;
}
label {
display: block;
cursor: pointer;
content: "close";
}
/* Default State */
#wrapper {
display: block;
background: gray;
color: white;
text-align: center;
}
/* Toggled State */
input[type=checkbox]:checked ~ #menu {
display: block;
background: lightgray;
color: black;
top:0px;
}
.menuToggle ul{
display: none;
width: 100%;
}
#menu {
padding-top: 5px;
margin: 0px;
list-style: none;
}
<div id="wrapper">
<div class="menuToggle">
<label for="toggle-1">open</label>
<input type="checkbox" id="toggle-1"/>
<ul id="menu">
<li>CIT</li>
<li>Blackboard</li>
<li>Mcomms</li>
<li>Tables</li>
<li>Exams</li>
</ul>
</div>
</div>
With jQuery you could do it like the example below.
I think it is now almost like you wanted it. Maybe some styling improvements are required.
With the css hack I couldn't manage the text change. With js you have more possibilities. You could also improve/modify the animations.
$(function() {
var $menuButton = $('#openButton');
var $menu = $('#menu');
var btnToggleAnim = function() {
$menuButton.animate({opacity: 'toggle'}, "fast");
};
var menuToggleAnim = function() {
$('#menu').animate({
height:'toggle',
//opacity: 'toggle'
}, { duration: "slow" });
};
$('#closeButton,#openButton').on('click', function() {
menuToggleAnim();
btnToggleAnim();
});
});
*, html {
padding: 0px;
font-family: sans-serif;
}
a {
text-decoration:none;
}
#openButton {
display:block;
background: gray;
color: #fff;
text-decoration: none;
border: 2px solid lightgray;
border-radius: 15px;
}
#closeButton{
display: block;
background: gray;
color: #fff;
text-align: center;
border: 2px solid lightgray;
border-bottom-left-radius: 13px;
border-bottom-right-radius: 13px;
}
#wrapper {
display: block;
text-align: center;
}
#menu {
display: none;
background: lightgray;
color: black;
padding-top: 5px;
margin: 0px;
list-style: none;
}
#menu {
color: #000;
text-decoration: none;
border: 2px solid lightgray;
border-radius: 15px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="wrapper">
open
<ul id="menu">
<li>CIT</li>
<li>Blackboard</li>
<li>Mcomms</li>
<li>Tables</li>
<li>Exams</li>
<li>close</li>
</ul>
</div>