Абсолютная позиция не работает с подробной информацией в панели навигации - PullRequest
0 голосов
/ 04 мая 2020

Я пытаюсь построить адаптивную и доступную навигацию. Для этого я использую <details> и <summary> для навигации по подстраницам. Я начал с связанного примера и отредактировал код под свои нужды.

Я немного поигрался с ним и, при необходимости, получил мобильную версию. Однако я сталкиваюсь с проблемой позиционирования раскрывающихся списков в немобильной версии.

В связанном примере раскрывающиеся списки отображаются непосредственно под соответствующим родительским элементом. Насколько я вижу, это достигается с помощью position: absolute. При попытке сделать это в моей адаптированной версии, раскрывающийся список перемещается в верхний левый угол панели навигации. Если я изменю расположение, элементы будут выровнены правильно, однако они будут отображаться не как выпадающий список, а как новые линии. Тем самым они перемещают всю навигационную панель.

Может кто-то определить, где лежит моя ошибка?

Я добавил весь код ниже. Я ничего не изменил в javascript и просто добавил его сюда, чтобы запуск фрагмента кода действительно воспроизвел проблему.

Большое спасибо за любую помощь!

window.addEventListener("DOMContentLoaded",function() { 
    "use strict"
    
        // Das Navigationselement
        var navele = document.querySelector("#sitenav");
        if(!navele) return;
    
        // // Polyfill für IE und Edge  -> muss noch ausgelagert werden
        // var native_details = ('open' in document.createElement("details"));
        // if (!native_details) {
        //     var script = document.createElement('script');
        //     script.src = "details-polyfill.js";
        //     document.getElementsByTagName('head')[0].appendChild(script);
        // }
    
        // Alle details und summary
        var details = navele.querySelectorAll("details");
        var summary = navele.querySelectorAll("summary");
    
        // Fokussierbares Element hinter Navigation legen, für focusin-Event
        var span = document.createElement("span");
        span.tabIndex = 0;
        navele.appendChild(span);
        
        // Fürs css Klasse "withjs" setzen
        sitenav.className += " withjs";
        
        // Auf Seitenbreite reagieren und bei breiten Viewports Klasse "large" setzen
        var format;
        var mq = window.matchMedia("screen and (min-width:45em)");
        mq.addListener(mq_handler);
        mq_handler();				
        
        function mq_handler() {
            if(mq.matches) {
                details[0].setAttribute('open', 'open');
                summary[0].setAttribute('hidden', 'hidden');
                format = "large";
                sitenav.className += " large"
                gridcontainer.className += " large"
            }
            else {
                details[0].removeAttribute('open');
                summary[0].removeAttribute('hidden');
                format = "small";
                sitenav.className = sitenav.className.replace(" large","");
                gridcontainer.className = gridcontainer.className.replace(" large","");
            }
        }
        
        // Eventhandler
        window.addEventListener('click', klickhandler);
        window.addEventListener('touchstart', klickhandler);
        window.addEventListener('keydown', keyhandler);
        window.addEventListener('focusin', focusinhandler);
        
        // Aktion bei Klick, Touch und Tastendruck auf summary
        function klickhandler(e) {
            if (e.target.nodeName.toLowerCase() === 'summary') {
                // Bei Betätigung des summary andere Submenüs schließen
                closeAllwithout([e.target.parentNode,details[0]]);
            }
            else {
                // Bei Klick oder Touch außerhalb der Navigation alle Submenüs schließen
                if(!childOf(e.target,details[0])) closeAllwithout([]);
            }
        }
    
        // Bei Taste ESC alle Submenüs schließen
        function keyhandler(e) { 
            if(e.keyCode == 27) closeAllwithout([]);
        }
        
        // Bei Verlassen mit Tabulator, also bei Fokus außerhalb der Navigation, alle Submenüs schließen
        function focusinhandler(e) { 
            if(!childOf(e.target,details[0])) closeAllwithout([]);
        }
        
        // Alle Submenüs schließen, bis auf Elemente in nc
        function closeAllwithout(nc) {
            for(var i=1;i<details.length;i++) if(nc.indexOf(details[i]) == -1) details[i].removeAttribute('open');
            if(format == "small" && 	details[0].hasAttribute("open") && nc.indexOf(details[0]) == -1) {
                details[0].removeAttribute('open');
                summary[0].focus();
            }
        }
        
        // Ermitteln, ob child ein Kindelement von parent ist
        function childOf(child, parent) {
            while((child = child.parentNode) && child!==parent); 
            return !!child; 
        }
        
    });
body {
    margin-right: 1em;
    margin-left: 1em;
    margin-top: 0;
    margin-bottom: 0;
    background-color: lightgrey;
}

#gridcontainer {
    background-color: white;
    display: grid;
    grid-template-areas: 
        'header header'
        'navdetails navdetails'
        'maintext maintext'
        'pic pic'
        'foot foot';
}

#gridcontainer.large {
    display: grid;
    grid-template-areas:
        'header header header'
        'maintext maintext pic'
        'foot foot foot';
}

header {
    grid-row: 1 / span 1;
    height: 2em;
}

main {
	grid-area: maintext;
	color: black;
    font: 1.25em/1.3 Arial, sans-serif;
    padding: 0.5em;
    align-self: start;
}

aside {
    grid-area: pic;
    padding: 0.5em;
    align-self: center;
    justify-self: center;
}

footer {
    grid-area: foot;
	font: 0.8em/1.3 Arial, sans-serif, grey;
	padding: 0.5em;
    box-shadow: 0em 0em 1em 0.5em rgb(192, 192, 192);
    display: flex;
    flex-direction: row;
    justify-content: center;
}



/* Footer */

footer a {
	padding: 0.5em;
	color: rgb(137, 147, 124);
    text-decoration: none;
}

/* Text */
	

article {
	font: 1em/1.3 Arial, sans-serif;
	max-width: 100%;
} 

h1 {
	font: 2.5em/1.3 Arial, sans-serif, bold;
    margin-left: 0.2em;
}

h2 { 
	color: rgb(117, 72, 94);
	font: 1.5em/1.3 Arial black, sans-serif;
}



/* Pictures */

img {
    max-width: 100%;
}

#logo {
    grid-area: logo;
    padding: .2em;
    color: rgb(14, 28, 54)
}

nav {
    grid-area: navi;
    color: rgb(14, 28, 54);
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    height: max-content;
}



/* ################# Allgemeine Einstellungen und Einstellungen für schmale Viewports ##################### */


#sitenav *, #sitenav a { 
    color: rgb(14, 28, 54); 
    margin: 0;
    background-color: white;
}

#sitenav ul { 
    list-style-type: none; 
}

#sitenav ul ul { 
    padding-left: .5em; 
    padding-right: 0; 
    margin-right: 0;
}

#sitenav li a, #sitenav li summary { 
    display: flex;
    flex-direction: row-reverse; 
    padding: .5em; 
    line-height: 1.4em;
    justify-content: flex-end;
    white-space: nowrap; 
    text-decoration: none;
}

#sitenav li a:hover, #sitenav li summary:hover, #sitenav li a:focus, #sitenav li summary:focus { 
    background-color: lightgrey;
}

#sitenav ul details:not([open]) summary::after { 
    content: ' ►';
}

#sitenav ul details[open] summary::after { 
    content: ' ◄'; 
}

#sitenav > details:not([open]) > summary::before { 
    content: "☰"; 
    font-size: 1.9em; 
    padding: .5em;
}

#sitenav > details[open] > summary::before { 
    content: "×"; 
    font-size: 2.3em; 
    padding: .5em;
}

#sitenav > details {
    max-width: -webkit-max-content;
	max-width: -moz-max-content;
	max-width: max-content;
}

#sitenav > details > ul { 
    margin: 0; 
    padding: 0;
}

#sitenav summary { 
    cursor: pointer; 
}

#sitenav summary::-webkit-details-marker { 
    display: none; 
}

#sitenav summary { 
    list-style-type: none; 
}

#sitenav > details > ul > li[aria-current] { 
    border-left: 2px solid black; 
}

#sitenav { 
    position: fixed;
    top: 0;
    right: 1em;
    left: 1em;
    background-color: white;
}

#sitenav ul { 
    position: fixed; 
    right: 1em;
    left: 1em;
    top: 4.2em;
}

#sitenav ul ul { 
    position: relative;
    right: 0;
    left: 0;
    top: 0;
}

/* ########################## Einstellungen für breite Viewports ######################################### */


#sitenav.large > details > ul , #sitenav.large > details > ul > li { 
    display: flex;
    flex-direction: row; 
    /* margin: 0; */
}

#sitenav.large ul details:not([open]) summary::after { 
    content: ' ▼'; 
}

#sitenav.large ul details[open] summary::after { 
    content: ' ▲'; 
}

#sitenav.large > details > ul > li[aria-current] { 
    border-bottom: 2px solid black; 
    border-left: none; 
}

#sitenav.large li a, #sitenav.large li summary { 
    display: flex;
    flex-direction: row; 
    justify-content: start;
}


#sitenav.large ul {
    position: sticky; 
    right: 0;
    top: 1.7em;
}

#sitenav.large.withjs ul ul { 
    position: absolute;
    max-width: -webkit-max-content;
	  max-width: -moz-max-content;
    max-width: max-content;
    margin-left: -.5em; 
    margin-right: 0;
    margin-top: 1.1em; 
    padding-left: .5em; 
    border-radius: 0 0 .5em .5em;
}
<!doctype html>
<html lang="de">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <!--[if lt IE 9]>
	<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.min.js"></script>
	<![endif]-->
    <link rel="stylesheet" href="style/style.css">
    <title>Yoga Loccum</title>
</head>

<body>
    <div id="gridcontainer">

        <header>
            <nav id="sitenav">
                <h1 id="logo">Pagelogo</h1>
                <details>
                    <summary> </summary>
                    <ul>
                        <li aria-current="page"><a href="#">Startseite</a></li>
                        <li><a href="/">Page 1</a></li>
                        <li>
                            <details>
                                <summary>Page 2</summary>
                                <ul>
                                    <li><a href="/">Page 2.1</a></li>
                                    <li><a href="/">Page 2.2</a></li>
                                </ul>
                            </details>
                        </li>
                        <li>
                            <details>
                                <summary>Page 3</summary>
                                <ul>
                                    <li><a href="/">Page 3.1</a></li>
                                    <li><a href="/">Page 3.2</a></li>
                                </ul>
                            </details>
                        </li>
                    </ul>
                </details>
            </nav>
        </header>


        <main id="maintext">

            <h2>Welcome</h2>

            <article>

                <p> Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. </p>

                <p> Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. </p>

            </article>

        </main>

        <aside id="addpic">
            Here will be a picture
        </aside>


        <footer>
            <a tabindex="0" aria-current="page" id="active">Startseite</a>
            <a href=/>Impressum</a>
        </footer>

    </div>

    <script src="JavaScript/menu.js"></script>

</body>

</html>

1 Ответ

0 голосов
/ 05 мая 2020

После некоторых попыток я понял, что довольно близок к ответу. Чтобы сбросить положение двух выпадающих меню, нужно было только добавить left: auto; и right: auto; в качестве дополнительных атрибутов для #sitenav.large ul ul

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...