使用:focus为外部div设置样式?


70

当我开始在textarea中写文本时,我希望带有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>

它不能与焦点一起使用,因为DIV将不具有焦点,只有TextArea会具有焦点。我会想象一个DIV无论如何都不能聚焦,因为它是一个不可选择的元素
musefan 2011年

您需要使用JavaScript来实现此目的;就像div可以聚焦一样,如果单击了textarea,它将立即将其收回。JS小提琴演示; 在外部单击textarea将更改的边界div,但将textarea抢断焦点向后激活。
大卫说,请

Answers:


42

尽管不能仅通过CSS / HTML来实现,但是可以通过JavaScript来实现(不需要库):

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小提琴演示

顺便说一句,使用jQuery之类的库,以上内容可以简化为:

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

JS小提琴演示

参考文献:


4
+1获得详细答案(尤其是不需要jQuery的答案)
Michael Mior

7
引入:focus-within伪元素不再是最有效的答案!
Tekill

95

其他张贴者已经解释了为什么:focus伪类不够用,但是最后有一个基于CSS的标准解决方案。

CSS选择器级别4定义了一个新的伪类:

:聚焦于

MDN

:focus-withinCSS伪类的任何元素相匹配:focus 伪类比赛或具有后代的:focus 伪类比赛。(这包括影子树的后代。)

因此,现在有了:focus-within伪类-textarea在单击被单击时设置外部div的样式变得微不足道。

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

Codepen示范

注意: 浏览器支持:Chrome(60 +),Firefox和Safari


2
哇,没意识到这是存在的,这是一个如此有用的选择器修饰符!
OG肖恩

2
了不起的答案:)
Fareed Alnamrouti

2
到目前为止,最简单,最好的答案。不知道该选择器也存在。从我的测试中可以在Mozilla和Chrome中运行。
user3259435 '17

1
很棒,很棒
Usman Developer

只是想提一下,当静态元素(div,span等)与外部div内的输入元素混合在一起时,仍然需要tabindex,即使内部静态元素之一也需要焦点轮廓被点击。
萨扬·帕尔

71

DIV设置tabindex属性可以使元素获得焦点。这是工作示例。

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

有关详细信息focus,并blur,你可以看看这篇文章

更新: 这是另一个focus用于创建的示例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>


@NamanSood我已将代码包含在我的答案中。看看这个。
卡伦·基什米尔扬(Karlen Kishmiryan)2016年

1
这是跨浏览器黑客吗?
jayarjo

@jayarjo它对我有用。适用于Ubuntu的Mozilla Firefox版本。49.0
卡伦·基什米尔扬(Karlen Kishmiryan)2016年

1
没有输入时有效。如果单击div中的非输入dom,它将起作用。如果您在div中单击输入dom,则输入dom将捕获您的焦点事件并停止弹出。
ramwin '17

5

现在可以通过本文:focus-within中举例说明的css方法来实现: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>


3

简单使用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>


更简单的是,不要使用jquery,@DavidThomas提供了一个很好的示例,解决方案...加载jquery文件大约有什么意义。77-94kB这样的东西,还有更多……
nelek

@nelek,如果您仍然使用jQuery,那也是一个很棒的解决方案,也更加健壮(跨浏览器而无需花费很多时间在您甚至无法访问的浏览器上进行调试!)
Alexis Wilke

2

您可以在div标签之间切换。只需将一个tab索引添加到div。最好使用jQuery和CSS类来解决此问题。这是在IE,Firefox和Chrome(最新版本...未测试较旧版本)中测试过的有效示例。

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

2

根据规格

:focus伪类适用而一个元件具有焦点(接受键盘事件或其它形式的文本输入的)。

<div>不接受输入,所以它不能有:focus。此外,CSS不允许您基于定位元素的后代来设置元素的样式。因此,除非您愿意使用JavaScript,否则您无法真正做到这一点。


请注意,<div>如果您设置了contenteditable="true"属性,a可以获得焦点。但是在那种情况下,这可能不是答案。
Alexis Wilke

0

据我所知,您必须使用JavaScript来向上移动dom。

像这样:

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

您还需要加载jQuery库。



By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.