Verwenden von: Fokus, um äußere Div zu stylen?

70

Wenn ich anfange, Text in den Textbereich zu schreiben, möchte ich, dass der äußere Teil mit einem Klassenfeld den Rand fest anstatt gestrichelt dreht, aber irgendwie gilt der: Fokus in diesem Fall nicht. Wenn es funktioniert mit: active, warum funktioniert es nicht mit: focus?

Irgendwelche Ideen warum?

(Hinweis. Ich möchte, dass der Rand des DIV fest wird, NICHT die Textbereiche.)

div.box
{
    width: 300px;
    height: 300px;
    border: thin dashed black;
}

div.box:focus{
    border: thin solid black;
}

<div class="box">
    <textarea rows="10" cols="25"></textarea>
</div>
Weblurk
quelle
Es funktioniert nicht mit Fokus, da der DIV keinen Fokus hat, sondern nur der TextArea. Ich würde mir
vorstellen, dass
Sie müssten JavaScript verwenden, um dies zu erreichen. Während der Div fokussieren kann, nimmt der Textbereich ihn sofort zurück, wenn er angeklickt wird. JS Fiddle Demo ; Wenn Sie außerhalb von klicken, textareawerden die Ränder von geändert div, aber wenn Sie die textareaSteals aktivieren, konzentrieren Sie sich wieder.
David sagt, Monica

Antworten:

42

Dies kann zwar nicht allein mit CSS / HTML erreicht werden, aber mit JavaScript (ohne Bibliothek):

var textareas = document.getElementsByTagName('textarea');

for (i=0;i<textareas.length;i++){
    // you can omit the 'if' if you want to style the parent node regardless of its
    // element type
    if (textareas[i].parentNode.tagName.toString().toLowerCase() == 'div') {
        textareas[i].onfocus = function(){
            this.parentNode.style.borderStyle = 'solid';
        }
        textareas[i].onblur = function(){
            this.parentNode.style.borderStyle = 'dashed';
        }
    }
}

JS Fiddle Demo .

Im Übrigen könnte mit einer Bibliothek wie jQuery das Folgende auf Folgendes reduziert werden:

$('textarea').focus(
    function(){
        $(this).parent('div').css('border-style','solid');
    }).blur(
    function(){
        $(this).parent('div').css('border-style','dashed');
    });

JS Fiddle Demo .

Verweise:

David sagt, Monica wieder einsetzen
quelle
4
+1 für eine detaillierte Antwort (insbesondere eine, die jQuery nicht benötigt)
Michael Mior
7
Nicht mehr die effizienteste Antwort mit der Einführung von: Fokus innerhalb des Pseudoelements!
Tekill
95

Andere Poster haben bereits erklärt, warum die :focusPseudoklasse nicht ausreicht, aber schließlich gibt es eine CSS-basierte Standardlösung.

CSS Selectors Level 4 definiert eine neue Pseudoklasse:

: Fokus innerhalb

Von MDN :

Die :focus-withinCSS-Pseudoklasse stimmt mit jedem Element überein, mit dem die :focus Pseudoklasse übereinstimmt oder das einen Nachkommen hat, mit dem die :focus Pseudoklasse übereinstimmt. (Dies schließt Nachkommen in Schattenbäumen ein.)

Also jetzt mit der :focus-withinPseudo-Klasse - das Styling des äußeren Divs, wenn das textareaangeklickt wird, wird trivial.

.box:focus-within {
    border: thin solid black;
}

Codepen-Demo

NB: Browserunterstützung : Chrome (60+), Firefox und Safari

Danield
quelle
2
Wow, wusste nicht, dass es das gibt, das ist so ein nützlicher Selektor-Modifikator!
OG Sean
2
erstaunliche Antwort :)
Fareed Alnamrouti
2
Mit Abstand die einfachste und beste Antwort. Wusste nicht, dass dieser Selektor auch existiert. Funktioniert in Mozilla und Chrome aus meinen Tests.
user3259435
1
Großartig, es ist erstaunlich
Usman Developer
Ich möchte nur erwähnen, dass der Tabindex immer noch benötigt wird, wenn eine Mischung aus statischen Elementen (div, span usw.) und Eingabeelementen innerhalb des äußeren div vorhanden ist und die Fokuskontur auch dann benötigt wird, wenn eines der inneren statischen Elemente vorhanden ist wird angeklickt.
Sayan Pal
71

DIVElemente können fokussiert werden, wenn das tabindexAttribut festgelegt wird. Hier ist das Arbeitsbeispiel.

#focus-example > .extra {
  display: none;
}
#focus-example:focus > .extra {
  display: block;
}
<div id="focus-example" tabindex="0">
  <div>Focus me!</div>
  <div class="extra">Hooray!</div>
</div>

Weitere Informationen zu focusund blurfinden Sie in diesem Artikel .

Update: Und hier ist ein weiteres Beispiel focuszum Erstellen eines menu.

#toggleMenu:focus {
  outline: none;
}
button:focus + .menu {
  display: block;
}
.menu {
  display: none;
}
.menu:focus {
  display: none;
}
<div id="toggleMenu" tabindex="0">
  <button type="button">Menu</button>
  <ul class="menu" tabindex="1">
    <li>Home</li>
    <li>About Me</li>
    <li>Contacts</li>
  </ul>
</div>

Karlen Kishmiryan
quelle
@NamanSood Ich habe den Code in meine Antwort aufgenommen. Hör zu.
Karlen Kishmiryan
1
Ist das ein browserübergreifender Hack?
Jayarjo
@ Jayarjo Es funktioniert bei mir. Mozilla Firefox für Ubuntu, ver. 49.0
Karlen Kishmiryan
1
Es funktioniert, wenn Sie keine Eingabe haben. Wenn Sie im div auf den nicht eingegebenen Dom klicken, funktioniert dies. Wenn Sie im div auf den Eingabebereich klicken, erfasst der Eingabebereich Ihr Fokusereignis und stoppt das Pop-out.
Ramwin
5

Dies kann jetzt durch die CSS-Methode :focus-withinerreicht werden, die in diesem Beitrag erläutert wird: http://www.scottohara.me/blog/2017/05/14/focus-within.html

/*
  A normal (though ugly) focus
  pseudo-class.  Any element that
  can receive focus within the
  .my-element parent will receive
  a yellow background.
*/
.my-element *:focus {
  background: yellow !important;
  color: #000;
}

/*
  The :focus-within pseudo-class
  will NOT style the elements within
  the .my-element selector, like the
  normal :focus above, but will
  style the .my-element container
  when its focusable children
  receive focus.
*/
.my-element:focus-within {
  outline: 3px solid #333;
}
<div class="my-element">
  <p>A paragraph</p>
  <p>
    <a href="http://scottohara.me">
      My Website
    </a>
  </p>

  <label for="wut_email">
    Your email:
  </label>
  <input type="email" id="wut_email" />
</div>

Tekill
quelle
3

Einfache Verwendung von JQuery.

$(document).ready(function() {
  $("div .FormRow").focusin(function() {
    $(this).css("background-color", "#FFFFCC");
    $(this).css("border", "3px solid #555");
  });
  $("div .FormRow").focusout(function() {
    $(this).css("background-color", "#FFFFFF");
    $(this).css("border", "0px solid #555");
  });
});
    .FormRow {
      padding: 10px;
    }
<html>

<head>
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
</head>

<body>
  <div style="border: 0px solid black;padding:10px;">
    <div class="FormRow">
      First Name:
      <input type="text">
      <br>
    </div>
    <div class="FormRow">
      Last Name:
      <input type="text">
    </div>
  </div>

  <ul>
    <li><strong><em>Click an input field to get focus.</em></strong>
    </li>
    <li><strong><em>Click outside an input field to lose focus.</em></strong>
    </li>
  </ul>
</body>

</html>

Matthew Egan
quelle
Und am einfachsten, verwenden Sie nicht jquery , es gibt ein schönes Beispiel, Lösung, von @DavidThomas ... was ist der Punkt Laden jquery-Datei ca. 77-94kB für so etwas und vieles mehr ...
Nelek
@nelek, wenn Sie trotzdem jQuery verwenden, ist das eine großartige Lösung, auch robuster (browserübergreifend, ohne ewig mit dem Debuggen von Browsern zu verbringen, auf die Sie nicht einmal Zugriff haben!)
Alexis Wilke
2

Sie können zwischen div-Tags wechseln. Fügen Sie dem div einfach einen Registerkartenindex hinzu. Verwenden Sie am besten jQuery- und CSS-Klassen, um dieses Problem zu lösen. Hier ist ein Arbeitsbeispiel, das in IE, Firefox und Chrome getestet wurde (Neueste Versionen ... wurden nicht älter getestet).

<html>
    <head>
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
        <script type="text/javascript">
            var divParentIdFocus;
            var divParentIdUnfocus = null;

            $(document).ready(function() {              

                    $("div").focus(function() {
                        //$(this).attr("class", "highlight");
                        var curDivId = $(this).attr("id");

                        // This Check needs to be performed when/if div regains focus
                        // from child element.
                        if (divParentIdFocus != curDivId){
                            divParentIdUnfocus = divParentIdFocus;
                            divParentIdFocus = curDivId;
                            refreshHighlight();
                        }

                        divParentIdFocus = curDivId;
                    });


                    $("textarea").focus(function(){
                        var curDivId = $(this).closest("div").attr("id");

                        if(divParentIdFocus != curDivId){
                            divParentIdUnfocus = divParentIdFocus;
                            divParentIdFocus = curDivId;
                            refreshHighlight();
                        }
                    });

                    $("#div1").focus();
            });

            function refreshHighlight()
            {
                if(divParentIdUnfocus != null){
                    $("#" +divParentIdUnfocus).attr("class", "noHighlight");
                    divParentIdUnfocus = null;
                }

                $("#" + divParentIdFocus).attr("class", "highlight");
            }
        </script>
        <style type="text/css">
            .highlight{
                background-color:blue;
                border: 3px solid black;
                font-weight:bold;
                color: white;
            }
            .noHighlight{           
            }
            div, h1,textarea, select { outline: none; }

        </style>
    <head>
    <body>
        <div id = "div1" tabindex="100">
            <h1>Div 1</h1> <br />
            <textarea rows="2" cols="25" tabindex="101">~Your Text Here~</textarea> <br />
            <textarea rows="2" cols="25" tabindex="102">~Your Text Here~</textarea> <br />
            <textarea rows="2" cols="25" tabindex="103">~Your Text Here~</textarea> <br />
            <textarea rows="2" cols="25" tabindex="104">~Your Text Here~</textarea> <br />
        </div>
        <div id = "div2" tabindex="200">
            <h1>Div 2</h1> <br />
            <textarea rows="2" cols="25" tabindex="201">~Your Text Here~</textarea> <br />
            <textarea rows="2" cols="25" tabindex="202">~Your Text Here~</textarea> <br />
            <textarea rows="2" cols="25" tabindex="203">~Your Text Here~</textarea> <br />
            <textarea rows="2" cols="25" tabindex="204">~Your Text Here~</textarea> <br />
        </div>
        <div id = "div3" tabindex="300">
            <h1>Div 3</h1> <br />
            <textarea rows="2" cols="25" tabindex="301">~Your Text Here~</textarea> <br />
            <textarea rows="2" cols="25" tabindex="302">~Your Text Here~</textarea> <br />
            <textarea rows="2" cols="25" tabindex="303">~Your Text Here~</textarea> <br />
            <textarea rows="2" cols="25" tabindex="304">~Your Text Here~</textarea> <br />
        </div>
        <div id = "div4" tabindex="400">
            <h1>Div 4</h1> <br />
            <textarea rows="2" cols="25" tabindex="401">~Your Text Here~</textarea> <br />
            <textarea rows="2" cols="25" tabindex="402">~Your Text Here~</textarea> <br />
            <textarea rows="2" cols="25" tabindex="403">~Your Text Here~</textarea> <br />
            <textarea rows="2" cols="25" tabindex="404">~Your Text Here~</textarea> <br />
        </div>      
    </body>
</html>
Thomas Vanderhoof
quelle
2

Gemäß Spezifikation :

Die :focusPseudoklasse gilt, während ein Element den Fokus hat (akzeptiert Tastaturereignisse oder andere Formen der Texteingabe).

Das <div>akzeptiert keine Eingaben, kann es also nicht haben :focus. Darüber hinaus können Sie mit CSS keine Stile für ein Element festlegen, die auf der Ausrichtung auf seine Nachkommen basieren. Sie können dies also nur dann wirklich tun, wenn Sie bereit sind, JavaScript zu verwenden.

Jon
quelle
Beachten Sie, dass a <div>den Fokus erhalten kann, wenn Sie das contenteditable="true"Attribut festlegen . Aber in diesem Fall ist das wahrscheinlich nicht die Antwort.
Alexis Wilke
0

Soweit mir bekannt ist, müssen Sie Javascript verwenden, um den Dom zu bereisen.

Etwas wie das:

$("textarea:focus").parent().attr("border", "thin solid black");

Sie müssen auch die jQuery-Bibliotheken laden.

CBRRacer
quelle
0

Fokus innerhalb

.box:focus-within {
  background: cyan;
}

Lesen Sie hier mehr

Moliere
quelle