[css] Using :focus to style outer div?

When I begin writing text in the textarea, I want the outer div, with a class box, to have it's border turned solid instead of dashed, but somehow the :focus doesn't apply in this case. If it works with :active, how come it doesn't work with :focus?

Any ideas why?

(Note. I want the DIV's border to turn solid, NOT the textareas)

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>

This question is related to css focus stylesheet

The answer is


DIV elements can get focus if set the tabindex attribute. Here is the working example.

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

For more information about focus and blur, you can check out this article.

Update: And here is another example using focus to create a menu.

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


Other posters have already explained why the :focus pseudo class is insufficient, but finally there is a CSS-based standard solution.

CSS Selectors Level 4 defines a new pseudo class:

:focus-within

From MDN:

The :focus-within CSS pseudo-class matches any element that the :focus pseudo-class matches or that has a descendant that the :focus pseudo-class matches. (This includes descendants in shadow trees.)

So now with the :focus-within pseudo class - styling the outer div when the textarea gets clicked becomes trivial.

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

_x000D_
_x000D_
.box {_x000D_
    width: 300px;_x000D_
    height: 300px;_x000D_
    border: 5px dashed red;_x000D_
}_x000D_
_x000D_
.box:focus-within {_x000D_
    border: 5px solid green;_x000D_
}
_x000D_
<p>The outer box border changes when the textarea gets focus.</p>_x000D_
<div class="box">_x000D_
    <textarea rows="10" cols="25"></textarea>_x000D_
</div>
_x000D_
_x000D_
_x000D_

Codepen demo

NB: Browser Support : Chrome (60+), Firefox and Safari


focus-within

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

read more here


Some people, like me, will benefit from using the :focus-within pseudo-class.

Using it will apply the css you want to a div, for instance.

You can read more here https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-within


You can tab between div tags. Just add a tab index to the div. It's best to use jQuery and CSS classes to solve this problem. Here's a working sample tested in IE, Firefox, and Chrome (Latest versions... didn't test older).

<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>

As far as I am aware you have to use javascript to travel up the dom.

Something like this:

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

you'll need the jQuery libraries loaded as well.


Simple use JQuery.

_x000D_
_x000D_
$(document).ready(function() {_x000D_
  $("div .FormRow").focusin(function() {_x000D_
    $(this).css("background-color", "#FFFFCC");_x000D_
    $(this).css("border", "3px solid #555");_x000D_
  });_x000D_
  $("div .FormRow").focusout(function() {_x000D_
    $(this).css("background-color", "#FFFFFF");_x000D_
    $(this).css("border", "0px solid #555");_x000D_
  });_x000D_
});
_x000D_
    .FormRow {_x000D_
      padding: 10px;_x000D_
    }
_x000D_
<html>_x000D_
_x000D_
<head>_x000D_
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>_x000D_
</head>_x000D_
_x000D_
<body>_x000D_
  <div style="border: 0px solid black;padding:10px;">_x000D_
    <div class="FormRow">_x000D_
      First Name:_x000D_
      <input type="text">_x000D_
      <br>_x000D_
    </div>_x000D_
    <div class="FormRow">_x000D_
      Last Name:_x000D_
      <input type="text">_x000D_
    </div>_x000D_
  </div>_x000D_
_x000D_
  <ul>_x000D_
    <li><strong><em>Click an input field to get focus.</em></strong>_x000D_
    </li>_x000D_
    <li><strong><em>Click outside an input field to lose focus.</em></strong>_x000D_
    </li>_x000D_
  </ul>_x000D_
</body>_x000D_
_x000D_
</html>
_x000D_
_x000D_
_x000D_


This can now be achieve through the css method :focus-within as examplified in this post: http://www.scottohara.me/blog/2017/05/14/focus-within.html

_x000D_
_x000D_
/*_x000D_
  A normal (though ugly) focus_x000D_
  pseudo-class.  Any element that_x000D_
  can receive focus within the_x000D_
  .my-element parent will receive_x000D_
  a yellow background._x000D_
*/_x000D_
.my-element *:focus {_x000D_
  background: yellow !important;_x000D_
  color: #000;_x000D_
}_x000D_
_x000D_
/*_x000D_
  The :focus-within pseudo-class_x000D_
  will NOT style the elements within_x000D_
  the .my-element selector, like the_x000D_
  normal :focus above, but will_x000D_
  style the .my-element container_x000D_
  when its focusable children_x000D_
  receive focus._x000D_
*/_x000D_
.my-element:focus-within {_x000D_
  outline: 3px solid #333;_x000D_
}
_x000D_
<div class="my-element">_x000D_
  <p>A paragraph</p>_x000D_
  <p>_x000D_
    <a href="http://scottohara.me">_x000D_
      My Website_x000D_
    </a>_x000D_
  </p>_x000D_
_x000D_
  <label for="wut_email">_x000D_
    Your email:_x000D_
  </label>_x000D_
  <input type="email" id="wut_email" />_x000D_
</div>
_x000D_
_x000D_
_x000D_


As per the spec:

The :focus pseudo-class applies while an element has the focus (accepts keyboard events or other forms of text input).

The <div> does not accept input, so it cannot have :focus. Furthermore, CSS does not allow you to set styles on an element based on targeting its descendants. So you can't really do this unless you are willing to use JavaScript.


Examples related to css

need to add a class to an element Using Lato fonts in my css (@font-face) Please help me convert this script to a simple image slider Why there is this "clear" class before footer? How to set width of mat-table column in angular? Center content vertically on Vuetify bootstrap 4 file input doesn't show the file name Bootstrap 4: responsive sidebar menu to top navbar Stylesheet not loaded because of MIME-type Force flex item to span full row width

Examples related to focus

How to remove focus from input field in jQuery? Set element focus in angular way Bootstrap button - remove outline on Chrome OS X How can I set focus on an element in an HTML form using JavaScript? Set Focus on EditText Mobile Safari: Javascript focus() method on inputfield only works with click? Correct way to focus an element in Selenium WebDriver using Java Prevent the keyboard from displaying on activity start What are some reasons for jquery .focus() not working? How can I set the focus (and display the keyboard) on my EditText programmatically

Examples related to stylesheet

How to display 3 buttons on the same line in css Vertical align middle with Bootstrap responsive grid How to style SVG with external CSS? Add a link to an image in a css style sheet background-image: url("images/plaid.jpg") no-repeat; wont show up How to play CSS3 transitions in a loop? Stylesheet not updating Make a table fill the entire window HTML not loading CSS file In which order do CSS stylesheets override?