使用: 聚焦外部 div 样式?

当我开始在文本区域中编写文本时,我希望外部的 div 带有一个类框,它的边框变成实线而不是虚线,但是不知为何: focus 不适用于这种情况。如果它与: active 一起工作,为什么与: focus 不一起工作?

知道为什么吗?

(注意,我希望 DIV 的边框变成实线,而不是文本区域)

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>
190346 次浏览

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.

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.

While this can't be achieved with CSS/HTML alone, it can be achieved with JavaScript (without need of a library):

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.

Incidentally, with a library, such as jQuery, the above could be condensed down to:

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

JS Fiddle demo.

References:

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>

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

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

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.

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

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

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

.box {
width: 300px;
height: 300px;
border: 5px dashed red;
}


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

Codepen demo

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

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

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

focus-within

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

read more here

You can use **:focus-within** to give style to outer div whenever an inner element is focused.

Another way to do that is to add **tabIndex** to a div. Then you can easily give **:focus** to just a div.