Charles Okwuagwu Charles Okwuagwu - 5 months ago 14
CSS Question

set focus to a div when any of it's content elements are clicked

I use the following to set focus to a div when it is clicked or tabbed into.

It only works when I click the padding area inside the div.

Clicking on any of the child elements does not activate the div:focus.

Please how can I fix this?

CSS

.sidebar-message:link {
}

.sidebar-message:visited {
}

.sidebar-message:hover {
background-color: lightyellow !important;
outline-width: 0 !important;
}

.sidebar-message:focus {
background-color: khaki !important;
outline-width: 0 !important;
}


HTML

<div class="sidebar-message" tabindex="-1">
<a href="#" id="pending_{{id}}" data-id="{{id}}">
<div class="pull-left text-center">
<img alt="image" class="img-circle message-avatar" src="media/profile-pics/{{uid}}.jpg">
</div>
<div class="media-body">
<strong>{{{contact_name}}}</strong>
<span class="badge {{color}} pull-right{{hidden}}">{{unread}}</span>
<br>
<small class="text-muted">{{formatDate last_seen 'dddd, MMMM Do h:mm:ss a'}}</small>
<small class="pull-right">{{agent_name}}</small>
</div>
</a>
</div>


some notes:

1) there are multiple
.sidebar-message
rows (DIVs), and only one should be highlighted at a time

2) the list of
.sidebar-message
DIVs is not available @ DocumentReady, it becomes available when a XHR request returns data to be populated into a template via handlebars. One of the comments suggested late-binding to get round this

Answer

This will add a new class to the container when any of the childs get the focus.

Note: The added class gets not removed in this example once it is set. if you want to remove the focused class if the user clicks somewhere else, I suggest you implement a handler for focusout() accordingly.

Another note: I would advise agains calling .focus() on the container element (as suggested in two of the other answers), as this could steal the focus from your child elements, which in turn could mess with the usability, especially if you're planing on adding input elements to the container.

$(document).ready(function() {
  // use the following line to bind a focus handler to existing elements:
  // $(".sidebar-message *").on('focus', function() { 
  // use the following line for late binding (dynamically created elements):
  $(document).on("focus", ".sidebar-message *", function() {
    // remove class from all .sidebar-message elements
    $(".sidebar-message").removeClass("focused");
    // add class to nearest .sidebar-message element
    $(this).closest(".sidebar-message").addClass("focused");
  });
});
.sidebar-message:hover {
  background-color: lightyellow !important;
  outline-width: 0 !important;
}
.focused.sidebar-message:hover,
.focused {
  background-color: khaki !important;
  outline-width: 0 !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="sidebar-message" tabindex="-1">
  <a href="#" id="pending_{{id}}" data-id="{{id}}">
    <div class="pull-left text-center">
      <img alt="image" class="img-circle message-avatar" src="media/profile-pics/{{uid}}.jpg">
    </div>
    <div class="media-body">
      <strong>{{{contact_name}}}</strong>
      <span class="badge {{color}} pull-right{{hidden}}">{{unread}}</span>
      <br>
      <small class="text-muted">{{formatDate last_seen 'dddd, MMMM Do h:mm:ss a'}}</small>
      <small class="pull-right">{{agent_name}}</small>
    </div>
  </a>
</div>

<hr>

<div class="sidebar-message" tabindex="-1">
  <a href="#" id="pending_{{id}}" data-id="{{id}}">
    <div class="pull-left text-center">
      <img alt="image" class="img-circle message-avatar" src="media/profile-pics/{{uid}}.jpg">
    </div>
    <div class="media-body">
      <strong>{{{contact_name}}}</strong>
      <span class="badge {{color}} pull-right{{hidden}}">{{unread}}</span>
      <br>
      <small class="text-muted">{{formatDate last_seen 'dddd, MMMM Do h:mm:ss a'}}</small>
      <small class="pull-right">{{agent_name}}</small>
    </div>
  </a>
</div>

Comments