Be KreaTief

Responsive Dropdown Menu ✤✤✤✤(✤)

Ich habe schon ein paar Tutorials dazu geschrieben, wie ihr responsive Menus schreibt. Bei den komplizierteren, habe ich mich dabei bisher aber auf Frameworks oder andrer Leute Anleitungen verlassen. Mein letztes Menututorial ist aber auch schon eine Weile her. in der Zeit habe ich einiges gelernt und deswegen gibt es jetzt mein erstes "komplexes" Menu für euch. Und das alles nur, damit es für euch ganz einfach wird, das Menu zu verwenden.

I have written a few tutorials on here how to create a responsive menu. For the more complex ones I usually relied on framework or other people's explanations. But my last menu tutorial was written a while ago. In the meantime I learned a lot and that's why I am ready now to present a more complex menu today. And that's only because I wanted it to be super easy to use.





Intro

Angefangen hat es bei der Arbeit. Ich schrieb unseren kompletten Theme Style in Sass neu und erkannte dabei, dass das bisherige responsive Menu unbrauchbar war. Nach kurzer Besprechung war der Plan, ein Menu zu haben, dass sobald es keinen Platz mehr hat, off-canvas geht. Da wir zwei Menus im oberen Bereich unterzubringen hatten, wäre nach unten aufklappen einfach weniger schön.
Es hat eine Weile gedauert, aber am Ende sass ich mit etwas da, was man brauchen konnte und dank PHP waren die ganzen Dinge, die mir jetzt heute Kopfzerbrechen beschert haben, ganz schnell gelöst.
In Blogger gibt es aber kein PHP (und mein Gott, bin ich froh darum!) und deswegen habe ich kurzerhand beschlossen, dass ich das auch nur mit Sass kann. Und so kam es, dass ich zum ersten Mal Sass-Funktionen schrieb und zum Ziel kam. Ein Ziel, dass ihr euch auf der Demopage ansehen könnt und sehr gerne nun bei der Entstehung begleiten dürft.
It all started at work. I was rewriting our complete theme style in sass and realized while doing it that the current responsive menu was unusable. After a short discussion the plan was to have a menu that turns into an off-canvas navigation as soon as it collapses. Since we have two menus fairly close together, it would have been a little ugly to open them inside the content.
It took a while but in the end I had something that I could use and thanks to PHP all the things that took me ages to figure out today were done in no time.
In Blogger there is no PHP (don't get me wrong, I am so glad there isn't!) and that's why I decided I was able to do it in Sass only. And that's how I wrote Sass functions for the first time and reached my goal of the day. The result can be seen in my demopage and you are very welcome to keep on reading how this goal was achieved.

Demo

Vorbereitung

Geschrieben wird in Sass, also muss das auf dem Computer installiert sein. Ich verwende zum compilieren Prepros, weil es ein schönes grafisches Interface hat und mich vor dem Terminal bewahrt. Ausserdem kommt es direkt mit Autoprefixer und einer Livepreview an, die ich immer sehr gerne benutze. Ganz besonders Autoprefixer, weil ich dann keine Prefixe schreiben muss.
Ansonsten braucht es nur noch einen Editor (wer meine Posts liest, weiss dass mein Favorit Brackets ist) und ein bisschen Zeit.

Prep Time!

We write in Sass, you you need to have it installed on your computer. I use Prepros to compile because it has a nice GUI and saves me from the evil terminal. Also it comes with autoprefixer and livepreview which both make my life easier. Espescially Autoprefixer, I have writing prefixes.
Other than that you just need an Editor (if you know my blog you'll know my favourite is Brackets) and a bit of time.

Markup

Das Markup ist simepl, einfach das klassische Markup eines Menus. Ich habe es noch in eine Section gepackt, weil das Menu nur so breit sein soll, wie der Content, die Leiste aber die volle Breite füllen soll. Ausserdem habe ich den Elementen, die "droppen" sollen, noch eine Klasse gegeben. Ich gehe davon aus, dass ihr das mit zwei Menus macht, denn das ist das, was Sasstechnisch Probleme bereitet hat. Ein einzelnes Menu ist um einiges einfacher.
Für den responsiven Teil brauchen wir einen Link, der als Schalter fungiert. Ich habe auch einen dieser Links innerhalb des Menus platziert, falls der erste von der Navigation verdeckt wird. Und irgendwie soll man das ja auch wieder schliessen können.
Die Schalter bekommen noch ein eigenes Menu.
The markup is simple, just the classic nav markup, really. I just added in a section because I wanted the menu to have a max-width but the menu-background not. Also I added a class to each parent. And I will assume you do two navigations, because that's waht caused the trouble for me, just one menu is a lot easier.
For the responsive part, we need a link, which will act as a toggle. I also added one inside the menu. The second on closes the navbar, in case of the toggle link being covered up.
The toggles also get their own navbar.

<nav class="toggle_nav">
    <a href='#menu' class="toggle_link">
        <i class="fa fa-navicon"></i>
    </a>

    <a href='#menu2' class="toggle_link2">
        <i class="fa fa-navicon"></i>
    </a>
</nav>

<section class="top_menu">
<nav id='menu2'>
    <a href="#" class="toggle_link2"><i class="fa fa-close fa-lg"></i></a>
    <ul>
        <li class="parent"><a>KT Demos</a>
            <ul>
                <li><a href='http://bekreatief.github.io/demo/triangle_mania_sass'>Previous</a></li>
                <li class="disabled"><!--<a href='#'>-->Next<!--</a>--></li>
            </ul>
        </li>
       <li><a href='#'>Back to Article</a></li>
        <li><a href='https://github.com/bekreatief/bekreatief.github.io/tree/master/demo/responsive_dropdown'>See Source</a></li>
    </ul>
</nav>
</section>

<header></header>

<section class="main_menu">
<nav id='menu'>
    <a href="#" class="toggle_link"><i class="fa fa-close fa-lg"></i></a>
    <ul>
        <li class="parent"><a>Other Versions</a>
            <ul>
                <li><a href='/demo/responsive_dropdown/two'>Off-Canvas Only</a></li>
                <li><a href='/demo/responsive_dropdown/three'>Different Collapses</a></li>
                <li><a href="/demo/responsive_dropdown/four">off-canvas + bar</a></li>
            </ul>
        </li>
       <li><a href='#'>And some</a></li>
        <li><a href='#'>empty links</a></li>
        <li><a href="#">to fill up</a></li>
        <li><a href="#">the space</a></li>
    </ul>
</nav>
</section>

jQuery

Damit wir das off-canvas öffnen können, brauchen wir ein bisschen jQuery. Wir fügen beim Klicken auf den Link die Klasse active hinzu.
To be able to open up the off-canvas we add a bit of jQuery. We add a class to the menu as soon as the toggle link is clicked.

$(document).ready(function () {
    $(".toggle_link").click(function () {
        $("#menu").toggleClass("active");
    });

    $(".toggle_link2").click(function () {
        $("#menu2").toggleClass("active");
    });
});

Sass

Und dann schreiben wir Sass. Ich habe ein kleines Demo geschrieben in dem ich ein einzelnes Menu demonstriert habe, dann könnt ihr euch den Code ansehen und damit spielen.
And then we write Sass. I wrote a Demo for just one menu, then you can see the code and play around.

See the Pen cvsJr by Myri (@bekreatief) on CodePen.



Variations -> Functions!

Ihr seht, wenn ihr den Wert von der collapse Variable auf etwas setzt, was höher ist, als euer Bildschirm, dann könnt ihr das Menu nur off-canvas haben. Das fand ich eigentlich ganz cool, wenn man durch die Collapse-Werte definieren kann, wie die Navbar aussieht. Ausserdem hatten beide Menus den gleichen Punkt, an dem das responsive Menu einsetzt. Zum Teil gibt es da aber Grössenmässig sehr grosse Unterschiede. Ich wollte das aber möglich machen. Dafür brauchen wir Funktionen. Funktionen sind nicht sschwer, im Grunde ist auch das was wir machen ganz einfach. Es hat trotzdem etwa 3 Stunden gedauert, bis alles so funktioniert hat, wie ich es haben wollte, weil man ja noch die Idee haben muss. Und heute stand ich leicht auf dem Schlauch. Aber es ist eine Lösung zusammengekommen.
You see, by changing the collapse variable to a value higher than your screen resolution, you can have the menu off-canvas only. I liked that and wanted to keep that. Also I would really like to have different collapse points for each menu, because sometimes they differ so greatly in lenght. To achieve this we need functions. They are pretty simple, but it took me ages to figure out, I had a very slow day... However, it ended up working out.

Togglenav Collapse

Die erste Aufgabe war es, unterschiedliche Collapses zu haben. Der erste Schritt war die gemeinsame Variable für die beiden Menus aufzuteilen. dann aber, brauchte ich einen collapse wert für mein Schaltermenu.
Damit das Menu immer da ist, muss das Schaltermenu angezeigt werden, sobald das erste Menu verschwunden ist. Der Wert, der also gebraucht wird, ist der grössere der beiden.
Natürlich hätte ich einfach nachsehen können, aber das ist nicht der Zweck der Sache. Ziel ist es, die Werte anpassen zu können und dann nichts anderes mehr machen zu müssen. Wir müssen also entwerder die eine oder die andere Variable in unser Media Query einfügen.
Die Funktion macht genau das. Sie checkt ob der collapse-Wert des einen Menus grösser oder gleich des collapse-Werts des anderen Menus ist und gibt dann die Variable aus, die wir brauchen.
In Sass sieht das so aus:
The first task was having different breakpoints. The first step was to create two variables out of the one I had used before. One collapse for each navigation. But then cam the togglenav, which needed a collapse point too.
For the menu to be accessible at any times the togglenav has to apear, as soon as the first navigation breaks.
So we need to use the bigger of the two collpase points for the togglenav.
We will do this with a function that checks which one of the collaps points has the higher value and then returns the variable we need.
In Sass this looks like that:

@function toggle_collapse($tc, $mc){
    @if $mc <= $tc{
        @return $tc;

    } @else{
        @return $mc;
    }
}

$toggle_collapse: toggle_collapse($topnav_collapse, $mainnav_collapse);

.toggle_nav{
    // style
    
    @media screen and (max-width: $toggle_collapse){
        // more style
    }
}

Das hat super funktioniert, nur leider wurde mir dann mein zweiter Schalter auch schon angezeigt, obwohl ich den gar nicht haben wollte.
This works like a charm, but unforunately the secund button will be displayed too, even if we do not want it yet.

Buttonvisibility

Aus diesem Grund habe ich eine zweite Funktion geschrieben. Die sollte den Wert unseres Schalter Collapses mit dem entsprechenden Menu Collapse vergleichen und dann einen display-wert ausspucken.
For that reason I wrote another function that compared the toggle collapse with the menu collapse and then spit out a value for display respectively.

@function toggle_visible($tc, $nc){
    @if $tc == $nc{
        @return inline-block;
    }
    @if $tc != $nc{
        @return none;
    }
}

.toggle_link{
    display: toggle_visible($toggle_collapse, $mainnav_collapse);
}

.toggle_link2{
    display: toggle_visible($toggle_collapse, $topnav_collapse);
}

Min- & Max-Width

Das hat dann zu gut funktioniert, denn der ausgeblendete Schalter ist natürlich komplett weg gewesen. Also habe ich beschlossen, dass ich einfach ein media query schreibe, welches die Zeit zwischen den beiden Punkten beschreibt und dort kommt die Info rein. Auch dafür musste eine Funktion her, sogar zwei. Aber danach - danach funktionierte es einfach.
That worked too good, because the button stayed hiddn forever. So I decided to write a media query which described the point inbetween the two collapses. I needed a function for that, even two, but in the end - in the end it just worked.


@function max-width($tn, $mn){
    @if $tn < $mn{
        @return $mn;
    }

    @if $tn > $mn {
        @return $tn;
    }

    @if $tn == $mn{
        @return 100%
    }
}

@function min-width($tn, $mn){
    @if $tn < $mn{
        @return $tn;
    }

    @if $tn > $mn {
        @return $mn;
    }

    @if $tn == $mn{
        @return 0
    }
}

$maxw: max-width($topnav_collapse, $mainnav_collapse);
$minw: min-width($topnav_collapse, $mainnav_collapse);


.toggle_link{  
    @media screen and (max-width: $maxw) and (min-width: $minw){
        display: toggle_visible($toggle_collapse, $mainnav_collapse);
    }
}

.toggle_link2{
    @media screen and (max-width: $maxw) and (min-width: $minw){
        display: toggle_visible($toggle_collapse, $topnav_collapse);
    }
}

Ready2Use

Ich habe einiges gelernt bei der Sache, aber das ist nicht das einzige Resultat. Das ganze ist sozusagen Ready2Use. Laded es euch herunter, schreibt eure Links ins HTML, passt die Variablen an, compiliert und die CSS für euer responsives Dropdown Menu ist geschrieben :D
I learned a lot by writing this, but that's not the whole result. That thing basically is Ready2Use.
Download it, write your links in the HTML, adjust the variables, compile and the CSS for your responsive DropDown is ready to be put in your source code :D

Code
edit