Home > Software engineering >  CSS element automatically closing when active / selected
CSS element automatically closing when active / selected

Time:04-26

I have a searchbar, which is initially hidden until the user "hovers" over the div "searchbar". The issue I had was if the user did not stay hovered over the searchbar, it would then close and be hidden again. I wanted to change this to :active, meaning the user has to click to show and hide ... however, when changing the CSS to :active, the searchbar opens and instantly closes on itself. Also if I press once and hold down the mouse, it stays open...

Any suggestions where I am going wrong?

enter image description here

.searchbar{
    margin-bottom: auto;
    margin-top: auto;
    height: 60px;
    border-radius: 30px;
    padding: 10px;
    display: flex;
    }

.search_input{
color: #858585;
border: 0;
outline: 0;
background: none;
width: 0;
caret-color:transparent;
line-height: 40px;
transition: width 0.4s linear;
}

.searchbar:hover > .search_input{
padding: 0 10px;
width: 215px;
caret-color:#000;
transition: width 0.4s linear;
}

.searchbar:hover > .search_icon{
background: white;
color: #000;
}


.search_icon{
height: 40px;
width: 40px;
float: right;
display: flex;
justify-content: center;
align-items: center;
border-radius: 50%;
color:#858585;
text-decoration:none;
}

CodePudding user response:

You need to use :focus for this. But to get focus to work on a div you need to add tabindex="-1" to the div.

Because focus only works for 1 element. You can't focus on the input. Therefor we have to add a jQuery solution to fix it.

See snippet below! ✌️

$('#TmInM').on('focus', function () {
    $('#TmInM').addClass('focus');
    $('#search').focus();
}).on('blur', function (e) {
    $('#TmInM').removeClass('focus');
    $('#search').blur();
});
$('#search').on('focus', function () {
    $('#TmInM').addClass('focus');
    $('#search').focus();
}).on('blur', function (e) {
    $('#TmInM').removeClass('focus');
    $('#search').blur();
});
#TmInM {
    width:40vw;
    height:3.4vh;
    background: #FFF;
    display: inline-block;
    margin-left:10vw;
    margin-top:0.9vh;
    color:#777;
    border:2px solid transparent;
    outline:none;
    border-radius:4px;
    -webkit-box-shadow:0px 0px 1px 1px #BBB;
    -moz-box-shadow:0px 0px 1px 1px #BBB;
    box-shadow:0px 0px 1px 1px #BBB;
}
#TmInM.focus {
    border:2px solid #00b646;
    outline:none;
}
#TmInM img {
    float: left;
    margin-top:0.4vh;
    margin-left:0.4vw;
    opacity: 0.2;
}
#TmInM input {
    width:30vw;
    height:1.8vh;
    padding:0.2vw;
    margin-top:0.2vh;
    margin-left:0.2vw;
    font-size:0.8vw;
  border:0;
}
#TmInM input::placeholder {
    color:#CCC;
    font-style:italic;
}
#TmInM input:focus {
    border:2px solid transparent;
    outline:none;
    -webkit-box-shadow:0px 0px 1px 1px #FFF;
    -moz-box-shadow:0px 0px 1px 1px #FFF;
    box-shadow:0px 0px 1px 1px #FFF;
}
#TmInM input:focus::placeholder {
    color:#999;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="TmInM" tabindex="-1">
            <img src="<?php echo $baseURL; ?>images/search.png" alt="" /><input type="text" name="search" id="search"  placeholder="Send out a leprechaun to go search what u are looking for..." value="" />
        </div>

CodePudding user response:

Update

OP also needs the input to stay in the "open" state after it has been clicked and returned back to the "closed" state when clicked again. There were changes to the markup:

  1. Add a hidden checkbox
  2. .searchbar is a <label>
  3. .search-icon is a <b> because an interactive tag like <a> will usually result in unexpected behavior when it is in another interactive tag (like <label>).

The toggling feature is possible by leveraging the checkbox/radio button association with <label>:

Figure I

// checkbox is display: none
<input id='switch' type='checkbox'>
//        ⇳ id and for must match
<label for='switch' class='searchbar'>
  <input id='search' type='search'><b 
  ...
</label>

when a chk/rad input is associated to a <label> -- whenever one is clicked by the user, the other is also clicked remotely. In oder to enable an association, the chk/rad must have an id and the <label> must have a [for] attribute with the chk/rad id (see figure I).

When the <label> is clicked so is the checkbox which in turn changes it's state to :checked. Once checked, it can change all tags that proceed it by the use of adjacent sibling combinator, general sibling combinators, and descendant combinators. Unfortunately, it's not perfect -- because the <label> is not clickable where the input#search resides. Only the areas to the left and right of #search is clickable. I made some outlines to popup whenever the <label> is clicked to indicate to the user that it's in a "locked" state.

:active state only happens when the user keeps the mouse button down. Use :focus on the input. The user clicks the input once and it's in the full length state until the user clicks elsewhere. The .search-icon can be controlled as well be using the adjacent sibling combinator:

Figure II

#search:focus   .search-icon {...
/* If input is focused by user then if the next tag has class 
.search-icon, apply the styles on .search-icon */

html {
  font: 2ch/1.25 'Segoe UI'
}

.searchbar {
  display: flex;
  justify-content: center;
  align-items: center;
  margin: 50px auto;
  padding: 0;
  line-height: 40px;
  border: 4px groove lightgrey;
  border-radius: 5px;
  cursor: pointer;
}

#search {
  display: inline-block;
  font: inherit;
  width: 0;
  border: 0;
  outline: 0;
  background: none;
  caret-color: transparent;
  height: 40px;
  transition: width 0.4s linear;
}

.searchbar:hover #search,
#search:focus,
#switch:checked .searchbar #search {
  width: 75%;
  margin: 0 12px;
  padding: 2px 4px;
  border: 3px inset rgba(129, 129, 129, 0.3);
  border-radius: 5px;
  caret-color: #000;
}

#switch:checked .searchbar #search {
  outline: 3px navy solid;
}

#switch:checked .searchbar {
  background: #ddd;
}

.search-icon {
  display: flex;
  justify-content: center;
  align-items: center;
  margin-left: -5%;
  color: #858585;
  text-decoration: none;
  cursor: pointer;
}

.searchbar:hover .search-icon,
#search:focus .search-icon,
#switch:checked .searchbar .search-icon {
  margin-left: 0;
  padding: 5px;
  border: 2px groove grey;
  border-radius: 50%;
  transition: border 0.3s linear;
}

#switch:checked .searchbar .search-icon {
  outline: 3px navy solid;
  color: navy;
}

.fa-lg {
  display: inline-block;
  padding: 10px 2.5px;
}

#switch {
  display: none;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css" rel="stylesheet">

<input id='switch' type='checkbox'>
<label for='switch' >
  <input id='search' name='search' type='search'>
  <b ><i ></i></b>
</label>

  • Related