Reputation: 13787
I want to change parent <div>
style when a child <input>
element receives focus. Unfortunately, the following code does not work at all. Please help me how to do it?
#email {
opacity: 0.3;
}
#exampleInputEmail1:focus < #email {
background: #f90442;
}
<div class="form-group form-group-lg" id="email" tabindex="0">
<label>Email address</label>
<input type="email" class="form-control" id="exampleInputEmail1" placeholder="Email">
</div>
Upvotes: 2
Views: 2995
Reputation: 21
A long time has passed since this question, but I see that there is still no answer. You can do whatever you want like this:
#email:has(input:focus) {
/* some style */
}
Upvotes: 2
Reputation: 868
Quick update on this one, this can be sort of accomplished using focus-within:
/* Selects a <div> when one of its descendants is focused */
div:focus-within {
background: cyan;
}
Upvotes: 2
Reputation: 88
Unfortunately, there are no parent selectors in CSS, not even in CSS3.
You will have to use a workaround – namely javascript of some kind.
How to approach this with javascript has to be decided in each case. Arguably, the easiest and most "accessible" solution is probably to use jQuery, and there are quite a few options.
For example, you could target the parent wrapper with the :has()
selector:
$(".form-group").has(":focus")
This will target any element with class="form-group [...]"
that has an element with focus among its descendants (not just as an immediate child).
Or you can use the .closest()
function:
$(":focus").closest(".form-group")
Unlike the similar .parents()
function, .closest()
stops traversing up the DOM tree once the selector is matched. This likely makes .closest()
the more efficient option of the two here.
The two examples above are both lenient with respect to the DOM structure, and less likely to break if it changes. However, if the wrapper element will always be an immediate parent of the <input>
, you can use the .parent()
function (with an optional selector):
// Option 1: Targets the immediate parent
$("input:focus").parent()
// Option 2: Targets the immediate parent, but only if it's a div
$("input:focus").parent("div")
Example implementation of these 4 options, works by toggling an .infocus
class on the wrapper (also available as jsfiddle):
// Adds or removes a focus class.
function updateFocus(e) {
// Log the event to view details about it
// console.log(e);
// The "has focus" class name
var focusClass = "infocus";
// The wrapper element selector
var wrapperSel = ".form-group";
//*===========================================================
// Option 1: has(":focus")
// - needs only the wrapper selector
// ===========================================================
var wrapper = $(wrapperSel);
// Remove the class on all
//wrapper.each(function() { $(this).removeClass(focusClass);});
wrapper.removeClass(focusClass);
// Add class only to the one whose descendant has focus
wrapper.has(":focus").addClass(focusClass);
//*/
/* ===========================================================
// Option 2: closest()
// - needs the event and the wrapper selector
// ===========================================================
if (e.type === "focus") {
$(e.target).closest(wrapperSel).addClass(focusClass);
} else if (e.type === "blur") {
$(e.target).closest(wrapperSel).removeClass(focusClass);
}
//*/
/* ===========================================================
// Option 3: parents()
// - needs the event and the wrapper selector
// ===========================================================
if (e.type === "focus") {
$(e.target).parents(wrapperSel).addClass(focusClass);
} else if (e.type === "blur") {
$(e.target).parents(wrapperSel).removeClass(focusClass);
}
//*/
/* ===========================================================
// Option 4: parent()
// - needs only the event (the wrapper selector is optional)
// ===========================================================
if (e.type === "focus") {
$(e.target).parent().addClass(focusClass);
} else if (e.type === "blur") {
$(e.target).parent().removeClass(focusClass);
}
//*/
}
// Bind the updateFocus() function above to focus/blur of form elements.
$('input, textarea, select').on("focus", function(event) {
updateFocus(event);
}).on("blur", function(event) {
updateFocus(event);
});
.form-group {
opacity: 0.3;
}
.form-group.infocus {
opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="form-group">
<label>Email</label>
<input type="email" placeholder="Email">
</div>
<div class="form-group">
<label>Name</label>
<input type="text" placeholder="Name">
</div>
Upvotes: 2
Reputation: 18987
What you are asking for is not possible in CSS as of now. So only option is to use Jquery.
If interested read on..
Use jquery to bind a on focus
event on the input
element, And in this event you just need to access the parent
and change its background-color
.
Have a CSS like below.
.background-color-RED{
background-color:#f90442;
}
Jquery syntax like below.
$("#exampleInputEmail1").on('focus',function() {
$(this).parent().addClass('background-color-RED');
});
Extra: If you want to remove the background color when the user focus out of the input then you can use blur
event and handle it as below.
$("#exampleInputEmail1").on('blur',function() {
$(this).parent().removeClass('background-color-RED');
});
Upvotes: 0
Reputation: 75
Use jQuery.
$("#exampleInputEmail1").focus(function() {
//change style
});
Upvotes: 0