Changing Font Awesome icon through dataset [duplicate] - javascript

This question already has an answer here:
css ::before attr() and unicode
(1 answer)
Closed 8 months ago.
I'm trying to change a Font Awesome icon on action using JS.
I'm implementing the icon through pseudo element ::before.
Assigning the icon through CSS using content:'\f0c2' displays the icon fine, but if I transfer the string through a dataset - content: attr(data-content), it just renders the string on the page.
How can I get it to work? Is there a better way to do it?
Here's a JSFiddle with all relevant code I've used.
const element = document.querySelector('.data');
const btn = document.querySelector('.btn');
const changeIcon = () => {
element.dataset.content = '\\f185';
}
btn.addEventListener('click', changeIcon);
.container {
display: grid;
place-items: center;
margin-top: 6rem;
font-family: sans-serif;
color: lightblue;
gap: 1rem;
}
.btn {
padding: 1em 2em;
background-color: lightblue;
color: white;
border-radius: 10px;
}
.btn:hover {
background-color: white;
color: lightblue;
border: 1px solid lightblue;
}
.icon-before::before {
display: inline-block;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
font: var(--fa-font-solid);
margin-right: 0.2em;
}
.string::before {
content: '\f0c2';
}
.data::before {
content: attr(data-content);
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css" integrity="sha512-KfkfwYDsLkIlwQp6LFnl8zNdLGxu9YAA1QvwINks4PhcElQSvqcyVLLD9aMhXd13uQjoXtEKNosOWaZqXgel0g==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<div class='container'>
<h2 class='element string icon-before'>
Added through string
</h2>
<h2 class=' element data icon-before' data-content="\f0c2">
Added through dataset
</h2>
<a class='btn'>Press Me</a>
</div>

const changeIcon = () => {
element.dataset.content = String.fromCharCode(0xf0c2);
}

Related

How do I style a button as a toggle that changes styling when clicked

I'm using the following code to change prices in my pricing table:
function myFunction() {
var x = document.getElementById("prijs-small");
if (x.innerHTML === "17,50") {
x.innerHTML = "13,50";
} else {
x.innerHTML = "17,50";
}
var x = document.getElementById("prijs-medium");
if (x.innerHTML === "58") {
x.innerHTML = "30,50";
} else {
x.innerHTML = "58";
}
var x = document.getElementById("prijs-large");
if (x.innerHTML === "128,50") {
x.innerHTML = "61";
} else {
x.innerHTML = "128,50";
}
}
.prijs-button {
background-color: white;
color: #012d5d;
padding: 10px 20px;
border-radius: 30px;
}
<button class="prijs-button" onclick="myFunction()">150/350</button>
<div id="prijs-small">17,50</div>
<div id="prijs-medium">58</div>
<div id="prijs-large">128,50</div>
Now I want to style a toggle that does the same, with on the one side showing 150 (people icon) and other side 350 (people icon) as shown in this example:
As I'm using a button now to make the prices change, how can I turn this into this toggle? The green half should be the active part.
Thanks so much in advance!
Will this do? I've used a checkbox and styled it to look like a pill. Hopefully it's self-explanatory but if not drop me a comment and I'll elaborate.
body {
background-color: gray;
}
#mybutton {
width: 8rem;
height: 3rem;
border-radius: 100rem;
overflow: hidden;
}
#mybutton input {
display: none;
}
#mybutton>label {
display: flex;
}
.side {
width: 50%;
padding-inline: 0.15rem;
text-align: center;
line-height: 3rem;
background-color: white;
transition: background-color, color 300ms;
cursor: pointer;
}
#mybutton input:not(:checked)~.left {
background-color: #35CB8C;
color: white;
transition: background-color, color 300ms;
}
#mybutton input:checked~.right {
background-color: #35CB8C;
color: white;
transition: background-color, color 300ms;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css" integrity="sha512-xh6O/CkQoPOWDdYTDqeRdPCVd1SpvCA9XXcUnZS2FmJNp1coAFzvtCN9BmamE+4aHK8yyUHUSCcJHgXloTyT2A==" crossorigin="anonymous" referrerpolicy="no-referrer"
/>
<div id='mybutton'>
<label for='mybutton-checkbox'>
<input type=checkbox id='mybutton-checkbox'>
<div class='side left'>25<i class="fa fa-user" aria-hidden="true"></i></div>
<div class='side right'>100<i class="fa fa-user" aria-hidden="true"></i></div>
</label>
</div>
You can put two buttons next to each other with some border radiuses applied to them.
Some POC version here:
div.toggle {
font-size: 0; /* this is to remove empty inline space between two buttons. if you don't like it, you can use flexbox */
}
button {
width: 100px;
height: 50px;
font-size: 14px;
}
button.left {
border-right-width: 0;
border-radius: 20px 0 0 20px;
}
button.right {
border-radius: 0 20px 20px 0;
}
<div class="toggle">
<button class="left">25</button>
<button class="right">100</button>
</div>
Adding an image or icon inside button is totally possible so you can do if if you want.
By inserting two buttons with different images you might get the result you are seeking.
Then by using in CSS border-bottom-left: (The amount of px you want)px and border-top-left: (The amount of px you want)px you can style you buttons.

Is there a way to change the value of any one button in a set of buttons at a time when one of them is clicked?

im looking for a way to change the backgroundColor of only the button which is clicked in a set of 4 buttons in react. Example:- default color is white, if the 2nd button is clicked its background color becomes blue, if the 4th button is clicked its bg color becomes blue but all others become white. I could do it with getElementBy classes/id or queryselector but the thing is it is present in 4 columns so it messes with the same button number in the other rows.
If you dont get what I mean, see the image.
export default function Quiz() {
const [quiz, setQuiz] = React.useState([]);
function getQuiz() {
fetch("my api key")
.then((res) => res.json())
.then((data) => setQuiz(data["results"]));
}
//the api gives 5 questions with 4 options each
React.useEffect(() => {
getQuiz();
}, []);
const renderQuiz = quiz.map((val) => {
// im using decodeURIComponent since its a "url base" or something type array.
let question = decodeURIComponent(val["question"]);
let correctAnswer = decodeURIComponent(val["correct_answer"]);
let wrongOptions = val["incorrect_answers"];
let allOptions = [];
wrongOptions.map((elem) => allOptions.push(decodeURIComponent(elem)));
allOptions.push(correctAnswer);
allOptions = shuffle(allOptions); //suffle is a function in another file which shuffles the contents of an array.
function RenderOptions() {
return allOptions.map((val) => {
return (
<>
<button className="opt-btn">{val}</button> {" "}
</>
);
});
}
return (
<div className="container">
<div className="question">{question}</div>
<div className="options">
<RenderOptions />
</div>
<hr className="dash" />
</div>
);
});
return <div className="quiz">{renderQuiz}</div>;
}
CSS
#import url("https://fonts.googleapis.com/css2?family=Karla&display=swap");
#import url("https://fonts.googleapis.com/css2?family=Inter&display=swap");
body {
background-color: #f5f7fb;
height: 100%;
overflow: hidden;
}
.quiz {
display: block;
margin: auto;
text-align: center;
margin-top: 30px;
width: 800px;
}
.question {
font-family: "Karla";
font-style: normal;
font-weight: bold;
font-size: 16px;
line-height: 19px;
color: #293264;
padding-top: 10px;
padding-bottom: 15px;
text-align: justify;
}
.options{
text-align: left;
max-width: 700px;
}
.opt-btn {
border: 0.794239px solid #4d5b9e;
width: -moz-fit-content;
width: fit-content;
box-sizing: border-box;
border-radius: 7.94239px;
padding-left: 15px;
padding-right: 15px;
padding-top: 5px;
padding-bottom: 5px;
background: #f5f7fb;
font-family: Inter;
font-style: normal;
font-weight: 600;
font-size: 11px;
line-height: 12px;
text-align: justify;
color: #293264;
}
.dash {
width: 630px;
height: 0px;
border: 0.794239px solid #dbdef0;
transform: rotate(-0.05deg);
margin-left: 0;
}
Will give more info if needed.

Each card does not open and close as expected when dynamically created with JavaScript

"use strict";
const openModal = document.querySelector('[data-create]');
const exitModal = document.querySelector('[data-close]');
const saveBtn = document.querySelector('#save');
openModal.addEventListener('click', showModal);
exitModal.addEventListener('click', closeModal);
saveBtn.addEventListener('click', saveCard);
/*
Detects if text has been inputed. If not, an error is shown
if yes the createFlashCard and closed modal function are called.
*/
function saveCard() {
let questionArea = document.querySelector('#question');
let answerArea = document.querySelector('#answer');
let showAlert = document.querySelector('.show-error-message');
if (questionArea = null || questionArea.value == '') {
if (answerArea = null || answerArea.value == '') {
showAlert.classList.remove("hide-error");
}
setTimeout(() => {
showAlert.classList.add("hide-error");
}, 3000);
} else {
closeModal();
createFlashCard();
}
}
/*
Removes the is-hidden css class to open modal
*/
function showModal(e) {
let modal = document.querySelector('.modal-design');
modal.classList.remove("is-hidden");
}
/*
Adds the is-hidden css class to close modal
*/
function closeModal() {
let modal = document.querySelector('.modal-design');
modal.classList.add('is-hidden');
}
/*
Creates a flash card using input string values.
Then renders a card using the .innerHTML property.
Each card rendered will be clickable to show the answer.
*/
function createFlashCard() {
let questionText = document.querySelector('.question-text').value;
let answerText = document.querySelector('.answer-text').value;
let cardSection = document.querySelector('.card-container');
let createArticle = document.createElement('article');
createArticle.className += "card";
createArticle.innerHTML = `
<div class="card-question-button">
<h4 id="title">${questionText}</h4>
<button id="show">></button>
</div>
<div id="answer-card">
<p id="answer-card-p">${answerText}</p>
</div>`;
cardSection.appendChild(createArticle);
openCloseCards();
}
function openCloseCards() {
let buttons = document.querySelectorAll('.card-question-button');
buttons.forEach(function (btn) {
btn.addEventListener('click', function (e) {
let questions = e.currentTarget.parentElement;
questions.classList.toggle("show-text");
})
})
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
line-height: 1.5;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
}
/*
variables
*/
:root {
--primary-color:#5dcbd8;
--secondary-color: hsl(186, 100%, 94%);
--third-color: #F6F6F8;
--fourth-color: #fff;
--button-border: none;
--error-color: hsl(0deg 58% 70%);
--shadow: 0px 2px 3px 0 hsla(0 , 0%, 0%, 0.2);
}
header {
padding: 15px;
color: var(--third-color);
height: 100px;
background-color: var(--primary-color);
}
/**
Prompt question card
*/
.prompt-question {
display: flex;
padding: 15px;
align-items: center;
justify-content: space-around;
}
#create {
border: var(--button-border);
border-radius: 5px;
background-color: var(--secondary-color);
height: 60px;
width: 70px;
font-size: 25px;
transition: .3s ease-in-out;
}
#create:hover {
cursor: pointer;
background-color: #b5f0f7;
}
/*
Modal Design
*/
.modal-placement{
display: flex;
justify-content: center;
}
.modal-design {
width: 600px;
padding: 20px;
display: flex;
flex-direction: column;
justify-content: space-between;
background-color: #F6F6F8;
box-shadow:var(--shadow);
border-radius: 4px;
margin: 30px;
}
.is-hidden {
visibility: hidden;
opacity: 1;
}
.erase-modal-c {
display: flex;
justify-content: flex-end;
}
#erase {
background-color:var(--error-color);
display: flex;
justify-content: center;
border: none;
padding: 5px;
height: 25px;
width: 25px;
}
#close {
margin-top: -8px;
margin-left: 3px;
font-size: 20px;
transform: rotate(45deg);
}
#erase:hover {
cursor: pointer;
}
h3 {
padding-top: 15px;
}
/**
Textarea design
*/
#question, #answer {
height: 90px;
}
textarea {
font-size: 15px;
padding: 4px;
resize: vertical;
}
#save {
border: var(--button-border);
margin-top: 25px;
height: 45px;
font-size: 15px;
background-color:var(--primary-color);
color: var(--third-color);
}
#save:hover {
cursor: pointer;
background-color: #90d8e0;
}
.show-error-message {
background-color: var(--error-color);
color: var(--fourth-color);
margin-top: 15px;
padding: 10px;
text-align: center;
}
.hide-error {
visibility: hidden;
opacity: 0;
}
/*
Card container
*/
.card-container {
display: grid;
background-color: var(--third-color);
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr;
margin-top: 40px;
}
#title {
margin-left: 10px;
}
.card {
display: flex;
margin: 20px;
flex-direction: column;
align-items: center;
background-color:var(--fourth-color);
padding: 7px;
justify-content: space-between;
box-shadow:var(--shadow);
border-radius: 5px;
transition: .3s ease-in-out;
z-index: 1000;
}
.card-question-button {
display: flex;
justify-content: space-between;
padding: 5px;
width: 100%;
}
.card-question-button:hover {
cursor: pointer;
}
/*
Answer card
*/
#answer-card {
display: none;
border-top: 1px solid rgba(0, 0, 0, 0.2);
padding: 15px;
text-align: left;
}
#answer-card-p {
text-align: left;
}
.show-text #answer-card {
display: block;
}
#show {
border: none;
background-color: var(--fourth-color);
font-size: 20px;
transition: .2s ease-in-out;
}
#show:hover {
cursor:pointer;
transform: translateX(-2px);
}
/* Media Queries */
#media screen and (max-width: 800px) {
.prompt-question {
box-shadow:var(--shadow);
border-radius: 4px;
margin: 20px;
}
.card-container {
grid-template-columns: 1fr;
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<header>
<h1>Flash Cards +</h1>
</header>
<article class="prompt-question">
<button id="create" data-create>+</button>
<p class="info">
Create a new card
</p>
</article>
<article class="modal-placement">
<section class="modal-design is-hidden">
<div class="erase-modal-c">
<button id="erase" data-close>
<p id="close">+</p>
</button>
</div>
<h3>Question</h3>
<textarea class="question-text textA" id="question"></textarea>
</div>
<h3>Answer</h3>
<textarea class="answer-text textA" id="answer"></textarea>
<button id="save">Save</button>
<div class="show-error-message hide-error">Please Submit Values</div>
</section>
</article>
<section class="card-container">
</section>
<script src="js/script.js"></script>
</html>
This is a flashcard project I am building. I am fairly new to programming and was looking for help on this particular bug that I cannot wrap my head around. Included in the gist is the css, html, and javascript code. Any tips on code structure is also appreciated.
Question:
When I dynamically create cards using JavaScript I want to show open and close behavior for each of them. The first card created does open and close as expected. However, the following cards do not. For example, one stays open while the other one closes.
I would like each card to open and close independently when clicked after dynamically being created. It seems the behavior is depending on the previous card.
When you call createFlashCard() The html that is generated:
<div class="card-question-button">
<h4 id="title">${questionText}</h4>
<button id="show">></button>
</div>
<div id="answer-card">
<p id="answer-card-p">${answerText}</p>
</div>
These elements will have the same ID's used more than once in a page when they should be unique. Add a unique identifier or remove the id attribute if its not needed. For example:
let cardCount=0;
function createFlashCard() {
cardCount++;
let questionText = document.querySelector('.question-text').value;
let answerText = document.querySelector('.answer-text').value;
let cardSection = document.querySelector('.card-container');
let createArticle = document.createElement('article');
createArticle.className += "card";
let title="title"+ cardCount;
let buttonID="show"+cardCount;
...
<button id=${buttonID}>
...
}
When you are executing your openCloseCards function, you are creating multiple event listeners based on the number of items in buttons.
I'd recommend adding the event listener in your createFlashCard function and removing the function definition of openCloseCards and it's call.
With this change the code seems to working as it should.
function createFlashCard() {
let questionText = document.querySelector('.question-text').value;
let answerText = document.querySelector('.answer-text').value;
let cardSection = document.querySelector('.card-container');
let createArticle = document.createElement('article');
createArticle.className += "card";
createArticle.innerHTML = `
<div class="card-question-button">
<h4 id="title">${questionText}</h4>
<button id="show">></button>
</div>
<div id="answer-card">
<p id="answer-card-p">${answerText}</p>
</div>`;
cardSection.appendChild(createArticle);
createArticle.addEventListener('click', function(e) {
let questions = e.target.parentElement;
questions.classList.toggle("show-text");
console.log(questions.classList)
})
}

Add smooth transition when changing an element's display using JavaScript

I've added a search bar in the header that is set to display: none by default and I used js to make it appear on a button click via assigning a .show class which contains display: block !important to the search bar element (#search). It's working fine but my only problem is the rough transition from display: none to block, so I've been looking into ways to make this transition smooth and most of the answers I found were using jQuery, which I don't really want to do since I'm still in the learning phase of js, so if there's a way I can do this using vanilla js, please help me with it.
Here's my code https://jsfiddle.net/5jxLq9ck/
In CSS line 38, I add the .show utility class
.show {
display: block !important;
}
And I'm assuming I'll have to edit something in here (js) to get the desired effect:
function showSearch(e) {
e.preventDefault;
if (
e.target.classList.contains("show-btn") ||
e.target.classList.contains("fas")
) {
const searchBar = document.querySelector("#search");
searchBar.classList.add("show");
}
}
Additional question: is my use of e.preventDefault correct here? The functionality didn't work until I used it.
Thanks a lot in advance.
Here is an updated snippet, I've changed the input width for the animation. You can make it even more smooth by set the input height.
const searchDiv = document.querySelector("#search-div");
// ADD EVENT LISTENERS
searchDiv.addEventListener("click", showSearch);
// FUNCTION: SHOW SEARCH BAR ON BUTTON CLICK
function showSearch(e) {
e.preventDefault;
if (
e.target.classList.contains("show-btn") ||
e.target.classList.contains("fas")
) {
const searchBar = document.querySelector("#search");
searchBar.classList.add("show");
}
}
/* GENERAL */
:root {
--light-color: #ccc;
--lighter-color: #f4f4f4;
--dark-color: #333;
--darker-color: #222;
--brand-color: #ff4;
--danger: #f44;
--danger-dark: #c00;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background: var(--dark-color);
color: var(--light-color);
font-family: "Trebuchet MS";
}
ul li {
list-style: none;
}
button,
input {
outline: none;
}
/* UTILITY */
.highlight {
color: var(--brand-color);
}
.show {
width: 300px !important;
border: black 2px solid;
padding: 0.6rem 1rem;
}
/* HEADER */
header {
background: var(--darker-color);
display: flex;
flex-direction: row;
align-items: center;
text-align: center;
justify-content: space-between;
padding: 1.4rem 6rem;
width: 100%;
}
#logo {
font-size: 2.4rem;
font-weight: 200;
}
#search-div {
width: auto;
height: auto;
display: flex;
gap: 0.4rem;
}
.show-btn {
padding: 0.6rem 0.7rem;
background: var(--light-color);
border-radius: 5px;
border: none;
transition: ease-in 300ms;
font-size: 1.2rem;
cursor: pointer;
height: 100%;
margin-top: 2px;
}
.show-btn:hover {
background: var(--brand-color);
transition: ease-in 300ms;
}
#search {
width: 0;
background: var(--lighter-color);
color: var(--darker-color);
height: 100%;
font-size: 1.2rem;
border-radius: 2px;
transition: ease-in 300ms;
border: none;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My Contact List</title>
<link rel="stylesheet" href="css/style.css">
<script src="https://kit.fontawesome.com/3ad7573e76.js" crossorigin="anonymous"></script>
</head>
<body>
<header>
<div id="logo-div">
<h1 id="logo">
<span class="highlight"><i class="fas fa-user-friends"></i></span> My<span
class="highlight">Contact</span>List
</h1>
</div>
<div id="search-div">
<button class="show-btn"><i class="fas fa-search"></i></button>
<input id="search" type="text" placeholder="Search contacts...">
</div>
</header>
<script src="js/main.js"></script>
</body>
</html>
You can make the transition from no display to block display smooth by playing with the opacity property so that when the element is given the "show" class it animates from an opacity of 0 to an opacity of 1 like so.
function showSearch(e) {
e.preventDefault;
if (
e.target.classList.contains("show-btn") ||
e.target.classList.contains("fas")
) {
const searchBar = document.querySelector("#search");
searchBar.classList.add("show");
}
}
document.getElementById("show").addEventListener("click", e => {
showSearch(e);
});
#keyframes smooth {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.show {
animation: smooth 1s ease;
display: block !important;
}
.none {
display: none;
}
<div class="none" id="search">Example</div>
<button class="show-btn fas" id="show">Show</button>

Disappearing drop down menu

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>

Categories

Resources