Hello. Today I tried to create a language button that has a drop down with other languages. I wanted the button to be round and not move other objects that are on the page. I didn't really succeed with this task.
I created a drop down button but not the way I wanted it to work. However wanted to share this maybe someone knows how you can achieve this. Further I will explain in more detail what I wanted to achieve and what problems I ran into.
Idea
I wanted to create a round button. When the round button is clicked a smooth sliding down transition should happen with other languages. Sounds pretty simple. Button that i made:
Button that i wanted:
It should have filled the middle with the background color. This was not achievable if I wanted that the expanded button wouldn't move any elements.
There were two main problems that I ran into. It's either I don't make the other languages position absolute and then other elements move around the screen when language options appear or make something like what i made there.
How I approached the problem
HTML
<header>
<nav>
<div class="company-name">ZS-DZINTRAS</div>
<ul class="navigation-links">
<li><a href="#">Flowers</a></li>
<li><a href="#">Bouquets</a></li>
<li><a href="#">Contact</a></li>
<li class="language-box">
<div class="main-langugage">
<span>LV</span>
<svg width="20" height="20" class="main-langugage-arrow">
<use
href="/src/Images/illustations.svg#icon-alert-triangle"
></use>
</svg>
</div>
<ul class="other-langague">
<li><span>ENG</span></li>
</ul>
</li>
</ul>
</nav>
</header>
There is pretty much a parent element - (language-box). Inside the parent element there are two child elements: one that shows the main language and the other that shows other languages - (main-langugage,other-langague).
CSS
.language-box {
position: relative;
background-color: $background;
color: $text;
justify-content: center;
align-items: center;
border-radius: 2rem;
font-family: "Lato", sans-serif;
font-size: 105%;
letter-spacing: 0.07rem;
font-weight: 500;
}
.main-langugage {
padding: 0.6rem;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
gap: 0.2rem;
&-arrow {
cursor: pointer;
transition: transform 0.3s ease-in-out;
transform: rotate(180deg);
color: $primary;
}
}
.other-langague {
position: absolute;
left: 0;
bottom: 0;
width: 100%;
background-color: inherit;
list-style: none;
display: flex;
flex-direction: column;
text-align: center;
gap: 0.5rem;
max-height: 0;
overflow: hidden;
transition: max-height 0.3s ease-in-out, padding 0.3s ease-in-out;
padding: 0;
transform: translateY(100%);
border-radius: 2rem;
}
.language-box.active {
.other-langague {
max-height: 150px;
padding: 0.5rem;
}
}
.language-box.active .main-langugage-arrow {
transform: rotate(0deg);//this rotates the arrow
}
}
The main thing that makes that other elements not move around when other languages are expanded - we make the parent element relative so that we can place other languages absolute to that parent element.
3iple dot (...) is other code that is not that important for that section.
.language-box {
position: relative;
...
}
.other-langague {
position: absolute;
left: 0;
bottom: 0;
...
}
This is cool but without a smooth drop down transition to make this more appealing. To make a drop down menu that does not fade or appear instantly in, we need to play with height and other spacing properties. Also we need to make the overflow hidden that the language options are not showing because it has position absolute and placed at the bottom of the parent element.
Before we can manipulate these properties that would expand other languages. First we need to set a active class to the parent element so that we know other languages should appear. You can probably do this with CSS or a bunch of other ways, but I use JS.
Javascript
document
.querySelector(".main-langugage-arrow")
.addEventListener("click", function () {
const languageButtonEl = document.querySelector(".language-box");
languageButtonEl.classList.toggle("active");
});
The javascirpt is pretty simple. All that is being done here that we are applying a active class when the language arrow is clicked.
When this toggles the active class now we need to look at this part of the CSS:
.other-langague {
max-height: 0;
padding:0;
transition: max-height 0.3s ease-in-out, padding 0.3s ease-in-out;
padding: 0;
transform: translateY(100%);
border-radius: 2rem;
...
}
.language-box.active {
.other-langague {
max-height: 150px;
padding: 0.5rem;
overflow: visible; //not necessary but there
}
}
.language-box.active .main-langugage-arrow {
transform: rotate(0deg);//this just rotates the arrow
}
So when the active class is added, other languages grow in size and space around the box (max-heihgt and padding). Also it moves down 100% Y axes so that it is not on top of it. This could also be achieved if we positioned the element 100% from top. Then the transfromY(100%) would not be needed but I did it this way. Like so:
.other-language{position: absolute; top:100%;...}
Hope I gave you some ideas on how to make these types of buttons if you didn't know. Not saying that is is the correct or the best way to do it. If you have any ideas how to make a button that I wanted or even some suggestions for the button that I have. Leave a comment hinting to something or a article that tried to do something like that. It would help me a lot. Have a nice day!
Top comments (0)