• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

:hover Problem

john

Neues Mitglied
Ich habe folgendes Problem.
Die h2's sind fest, die Anzahl der p's variieren.
Nun möchte ich per css beim hover den p's unterschiedliche Hintergrundfarben je nach Sektion h2 verpassen.
Bisher habe ich folgendes, hänge aber fest.

HTML:
<!DOCTYPE html>
<html lang="de">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style>
    p:hover{
      background:silver;
    }
  </style>
</head>
<body>
  <h1>Beispiel</h1>
  <h2>Test-1</h2>
  <p>test1-1</p>
  <p>test1-2</p>
  <p>test1-3</p>
  <h2>Test-2</h2>
  <p>test2-1</p>
  <p>test2-2</p>
  <h2>Test-3</h2>
  <p>test3-1</p>
</body>
</html>
 

Sempervivum

Senior HTML'ler
Ich empfehle, die Überschrift und die Absätze jeweils in ein section-Tag zu packen, dann wird es ganz einfach. Auch unter dem Gesichtspunkt der Semantik nicht verkehrt und macht das HTML besser lesbar:
Code:
<!DOCTYPE html>
<html lang="de">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        #section1 p:hover {
            background: silver;
        }

        #section2 p:hover {
            background: lightblue;
        }

        #section3 p:hover {
            background: lightpink;
        }
    </style>
</head>

<body>
    <h1>Beispiel</h1>
    <section id="section1">
        <h2>Test-1</h2>
        <p>test1-1</p>
        <p>test1-2</p>
        <p>test1-3</p>
    </section>
    <section id="section2">
        <h2>Test-2</h2>
        <p>test2-1</p>
        <p>test2-2</p>
    </section>
    <section id="section3">
        <h2>Test-3</h2>
        <p>test3-1</p>
    </section>
</body>

</html>
 

john

Neues Mitglied
Vielen Dank,
leider ist das so nicht möglich, weil ich das HTML über PHP inkludiere und dieses aus einem Markdown Dokument kommt.
Deswegen habe ich gehofft, dass es mit CSS geht.
 

Sempervivum

Senior HTML'ler
Verstehe, wenn das so ist, kannst Du u. U. das HTML überhaupt nicht verändern, auch keine Klassen etc. hinzu fügen? Irgend wie brauchst Du ja ein Kriterium um die unterschiedlichen Farben fest zu legen.
 

Sempervivum

Senior HTML'ler
OK, dann musst Du dich an der Reihenfolge orientieren. Dies habe ich gerade getestet und funktioniert:
Code:
        h2:first-of-type~p:hover {
            background-color: silver;
        }

        h2:nth-of-type(2)~p:hover {
            background-color: lightblue;
        }

        h2:nth-of-type(3)~p:hover {
            background-color: lightpink;
        }
HTML wie in deinem Eingangsposting.
 

john

Neues Mitglied
Jetzt habe ich gedacht, dass ich wenn ich auf h2 clicke, den jeweiligen Part ausblenden kann.
Das klappt aber so nicht immer. Was mache ich verkehrt?


HTML:
<!DOCTYPE html>
<html lang="de">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
   <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
  <style>
    h2{
      cursor:pointer;
    }
    h2:first-of-type~p:hover {
      background-color: silver;
    }
    h2:nth-of-type(2)~p:hover {
      background-color: lightblue;
    }

    h2:nth-of-type(3)~p:hover {
      background-color: lightpink;
    }
  </style>
</head>
<body>
  <h1>Beispiel</h1>
  <h2>Test-1</h2>
    <p>test1-1</p>
    <p>test1-2</p>
    <p>test1-3</p>
  <h2>Test-2</h2>
    <p>test2-1</p>
    <p>test2-2</p>
  <h2>Test-3</h2>
    <p>test3-1</p>
  <script>
    $('h2:first-of-type').on('click', () => $('h2:first-of-type~p').toggle())
    $('h2:nth-of-type(2)').on('click', () => $('h2:nth-of-type(2)~p').toggle())
    $('h2:nth-of-type(3)').on('click', () => $('h2:nth-of-type(3)~p').toggle())
  </script>
</body>
</html>
 

Sempervivum

Senior HTML'ler
Nein, so klappt das leider nicht. Aber wenn wir jQuery verwenden, können wir mit nextUntil() die folgenden p-Elemente ermitteln, eine Klasse toggeln und das Verbergen mit CSS erledigen, dann wird es sogar noch einfacher:
Code:
<!DOCTYPE html>
<html lang="de">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        h2:first-of-type~p:hover {
            background-color: silver;
        }

        h2:nth-of-type(2)~p:hover {
            background-color: lightblue;
        }

        h2:nth-of-type(3)~p:hover {
            background-color: lightpink;
        }

        p.hide {
            display: none;
        }
    </style>
    <script type="text/javascript" src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
</head>

<body>
    <h1>Beispiel</h1>
    <h2>Test-1</h2>
    <p>test1-1</p>
    <p>test1-2</p>
    <p>test1-3</p>
    <h2>Test-2</h2>
    <p>test2-1</p>
    <p>test2-2</p>
    <h2>Test-3</h2>
    <p>test3-1</p>
    <script>
        $('h2').on('click', (event) => {
            $(event.target).nextUntil('h2').toggleClass('hide');
        });
    </script>
</body>

</html>
 

Sempervivum

Senior HTML'ler
PS: jQuery ist bei mir etwas in den Hintergrund getreten, deshalb habe ich es unnötig kompliziert gemacht. So geht es auch:
Code:
        $('h2').on('click', (event) => {
            $(event.target).nextUntil('h2').toggle();
        });
Das CSS für das Verbergen kann dann entfallen.
 

john

Neues Mitglied
Oh vielen Dank,

ich habe es jetzt so gemacht:


Code:
<!DOCTYPE html>
<html lang="de">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
   <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
  <style>
    h2{
      cursor:pointer;
      user-select: none;
    }
    h2:first-of-type~p:hover {
            background-color: silver;
        }

        h2:nth-of-type(2)~p:hover {
            background-color: lightblue;
        }

        h2:nth-of-type(3)~p:hover {
            background-color: lightpink;
        }
  </style>
</head>
<body>
  <h1>Beispiel</h1>
  <h2>Test-1</h2>
  <p>test1-1</p>
  <p>test1-2</p>
  <p>test1-3</p>
  <h2>Test-2</h2>
  <p>test2-1</p>
  <p>test2-2</p>
  <h2>Test-3</h2>
  <p>test3-1</p>
  <script>
   $('h2').on('click', (event) => {
    $(event.target).nextUntil('h2').toggle();
   });
  </script>
</body>
</html>

Wenn ich aber auf das Test-3 clicke wird folgendes im Bildschirm gezeigt:


Screenshot 2022-03-29 073403.png
 

Sempervivum

Senior HTML'ler
Ist ja witzig, da habe ich gar nicht daran gedacht, dass das script-Tag einbezogen wird. Wir können das beheben, indem wir das script-Tag in den Selector einbeziehen:
Code:
        $('h2').on('click', (event) => {
            $(event.target).nextUntil('h2,script').toggle();
        });
 

john

Neues Mitglied
Aber dann müsste ich ja alle tags einbeziehen, die evtl. folgen könnten. Das ist nicht so gut.


Code:
<!DOCTYPE html>
<html lang="de">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
   <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
  <style>
    h2{
      cursor:pointer;
      user-select: none;
    }
    h2:first-of-type~p:hover {
            background-color: silver;
        }

        h2:nth-of-type(2)~p:hover {
            background-color: lightblue;
        }

        h2:nth-of-type(3)~p:hover {
            background-color: lightpink;
        }
  </style>
</head>
<body>
  <h1>Beispiel</h1>
  <h2>Test-1</h2>
  <p>test1-1</p>
  <p>test1-2</p>
  <p>test1-3</p>
  <h2>Test-2</h2>
  <p>test2-1</p>
  <p>test2-2</p>
  <h2>Test-3</h2>
  <p>test3-1</p>
  <h3>Anmerkungen</h3>
  <p>dies ist eine Anmerkung</p>
 
 
  <script>
   $('h2').on('click', (event) => {
    $(event.target).nextUntil('h2, script').toggle();
   });
  </script>
</body>
</html>
 

Sempervivum

Senior HTML'ler
Da hast Du auch wieder Recht. Man kann jedoch mit dem Selector auch prüfen, ob es sich um ein anderes Element als p handelt:
Code:
        $('h2').on('click', (event) => {
            $(event.target).nextUntil(':not(p)').toggle();
        });
 

Sempervivum

Senior HTML'ler
PS: Die geschweiften Klammern hatte ich nur zum Debuggen eingefügt, es geht natürlich auch ohne, so wie Du es gemacht hast.
 

john

Neues Mitglied
Vielen Dank,
so scheint es zu klappen. Leider wird der Absatz mit dem Inhalt "dies ist eine Anmerkung" durch das css von Dir auch farbig hinterlegt beim :hover. Wie bekomme ich das denn weg? Hast Du auch eine Idee, wie man das ohne jQuery erledigt.
 

Sempervivum

Senior HTML'ler
Möchtest Du ganz auf Javascript verzichten, auch auf das native? AFAIK wird das nicht gehen, wenn Du das HTML nicht ändern kannst.
Nur ohne jQuery kann man das problemlos auch erledigen.
Mit Javascript ist man auf jeden Fall flexibler. Mein CSS aus Posting #2 hat ja auch seine Tücken, wie Du gerade siehst.
 

Sempervivum

Senior HTML'ler
Leider kenne ich kein Äquivalent zu nextUntil() in Vanilla-JS, man wird das selbst implementieren müssen. Ist aber auch kein Hexenwerk. Man findet da einige Implementierungen, ich würde das jedoch mit einem Callback erledigen, damit man gleich eine Aktion während der Suche nach dem Endekriterium ausführen kann. Etwa so (ungetestet):
Code:
function nextUntil(startEle, selector, callback) {
    let nextEle = startEle.nextElementSibling;
    while (nextEle && !nextEle.matches(selector)) {
        callback(nextEle);
        nextEle = nextEle.nextElementSibling;
    }
}
Damit müsstest Du dann in einem ersten Schritt den Code in #14 umändern können. Und eine Klasse verwenden, wie früher schon gesagt. Versuche es und melde dich wieder wenn Du nicht zum Ziel kommst.
 
Zuletzt bearbeitet:
Werbung:
Oben