使用 :focus 设置外部 div 的样式?
Posted
技术标签:
【中文标题】使用 :focus 设置外部 div 的样式?【英文标题】:Using :focus to style outer div? 【发布时间】:2011-12-14 03:30:51 【问题描述】:当我开始在 textarea 中编写文本时,我希望带有类框的外部 div 的边框变为实心而不是虚线,但不知何故 :focus 在这种情况下不适用。如果它可以与 :active 一起使用,为什么它不能与 :focus 一起使用?
有什么想法吗?
(注意。我希望 DIV 的边框变为实心,而不是 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>
【问题讨论】:
它不适用于焦点,因为 DIV 没有焦点,只有 TextArea 有。我会想象一个 DIV 无论如何都不能有焦点,因为它是一个不可选择的元素 您需要使用 javascript 来实现这一点;因为虽然 div 可以集中注意力,但如果单击它,textarea 会立即将其收回。 JS Fiddle demo;在textarea
之外单击将更改div
的边框,但激活textarea
会抢回焦点。
【参考方案1】:
其他发帖者已经解释了:focus
伪类不足的原因,但终于有了基于CSS的标准解决方案。
CSS Selectors Level 4 定义了一个新的伪类:
:focus-within
来自MDN:
:focus-within
CSS 伪类匹配:focus
的任何元素 伪类匹配或具有:focus
的后代 伪类匹配。 (这包括影子树的后代。)
所以现在有了:focus-within
伪类 - 当textarea
被点击时,外部 div 的样式变得微不足道了。
.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
注意: Browser Support:Chrome (60+)、Firefox 和 Safari
【讨论】:
哇,没想到有这个,这是一个非常有用的选择器修饰符! 惊人的答案:) 迄今为止最简单和最好的答案。也不知道这个选择器存在。根据我的测试,在 Mozilla 和 Chrome 中工作。 太棒了,太棒了 只想提一下tabindex还是需要的,当有静态元素(div、span等)混合在一起的时候,还有外层div里面的input元素,并且需要焦点轮廓即使单击内部静态元素之一。【参考方案2】:如果设置tabindex
属性,DIV
元素可以获得焦点。这是工作示例。
#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
的更多信息,您可以查看this article。
更新:
这是另一个使用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 我已将代码包含在我的答案中。看看吧。 这是跨浏览器破解吗? @jayarjo 它对我有用。用于 Ubuntu 的 Mozilla Firefox,版本。 49.0 当你没有输入时它可以工作。如果单击 div 中的非输入 dom,它可以工作。如果点击 div 中的输入 dom,输入 dom 将捕获您的焦点事件并停止弹出。【参考方案3】:虽然这不能单独使用 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 Fiddle demo.
顺便说一句,使用 jQuery 之类的库,上面的内容可以浓缩为:
$('textarea').focus(
function()
$(this).parent('div').css('border-style','solid');
).blur(
function()
$(this).parent('div').css('border-style','dashed');
);
JS Fiddle demo.
参考资料:
getElementsByTagName()
.
onfocus
。
onblur
。
parentNode
。
tagName
。
toString()
。
toLowerCase()
。
style
。
focus()
。
blur()
。
parent()
。
css()
。
【讨论】:
+1 以获得详细答案(尤其是不需要 jQuery 的答案) 引入 :focus-within 伪元素不再是最有效的答案! 这是一个很好的答案,我认为仍然有效,因为 :focus-within 目前仍是一个工作草案。这正是我所需要的。谢谢。【参考方案4】:现在可以通过 css 方法 :focus-within
来实现这一点,如本文所示: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>
【讨论】:
【参考方案5】:简单使用 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,如果你仍然使用 jQuery,这是一个很好的解决方案,也更健壮(跨浏览器,无需永远在你甚至无法访问的浏览器上进行调试!)【参考方案6】:根据the spec:
:focus
伪类在元素具有焦点时应用(接受键盘事件或其他形式的文本输入)。
<div>
不接受输入,所以它不能有:focus
。此外,CSS 不允许您基于针对其后代的元素设置样式。因此,除非您愿意使用 JavaScript,否则您无法真正做到这一点。
【讨论】:
请注意,如果您设置contenteditable="true"
属性,<div>
可以获得焦点。但在那种情况下,这可能不是答案。【参考方案7】:
焦点内
.box:focus-within
background: cyan;
read more here
【讨论】:
【参考方案8】:您可以在 div 标签之间使用制表符。只需将选项卡索引添加到 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>
【讨论】:
【参考方案9】:据我所知,您必须使用 javascript 向上移动 dom。
类似这样的:
$("textarea:focus").parent().attr("border", "thin solid black");
您还需要加载 jQuery 库。
【讨论】:
以上是关于使用 :focus 设置外部 div 的样式?的主要内容,如果未能解决你的问题,请参考以下文章