making bootstrap 4 input like material search field, transition animation issue - html

i was trying to make bootstrap form input like material design search field. i have managed to make it but i guess there is a small issue with focus state and that is when i click the field, the underline animation runs smooth but, when i click outside of it the animation takes two steps to play. here is the code sample to understand better (i have downloaded bootstrap locally using npm)
in html =>
<div class="container">
<div class="d-flex mt-5">
<i type="submit" class="fa fa-search"></i>
<input type="email" class="form-control" placeholder="Search" />
</div>
</div>
in scss =>
.d-flex {
align-items: center;
}
.form-control {
border-top: 0;
border-left: 0;
border-right: 0;
border-bottom: 1px solid #eee;
border-radius: 0;
padding: 0;
}
.form-control:focus {
box-shadow: none;
border-bottom: 2px solid #4dd1e1;
transition: border-color 0.2s linear;
backface-visibility: hidden;
}
i.fa-search {
margin-top: 0.3rem;
margin-right: 1rem;
}
so, how can i fix this ?

Replace transition: border-color 0.2s linear; into .form-control
.form-control {
border-top: 0;
border-left: 0;
border-right: 0;
border-bottom: 1px solid #eee;
border-radius: 0;
padding: 0;
transition: border-color 0.2s linear; /* moved form :focus */
}
Because your animation activates only on :focus, but whithout :focus the .form-control doesn't now about animation and do the transformation harshly.

Related

Bootstrap input border flashing when clicking away from altered input:focus

I have a simple form with an input field where I created my own floating placeholder/label. I then wanted to change how the focus behave, removing shadow and alter the borders. Here is the code I have right now which is almost working:
.paddings{
padding: 5rem;
}
input.my-input:focus{
box-shadow: none;
border: thin solid rgba(0, 100, 173, 0.5);
border-top: none;
}
.floating-label{
color: rgb(80 80 80);
pointer-events: none;
position: absolute;
left: 2.5rem;
top: 0.5rem;
transition: 0.2s ease all;
}
input:focus ~ .floating-label{
color: rgb(40 40 40);
font-size: 0.85rem;
top: -0.65rem;
left: 2rem;
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#3.3.7/dist/css/bootstrap.min.css">
<div class="row paddings">
<div class="col-md-12">
<div>
<input class="form-control my-input" type="text">
<span class="floating-label">Search</span>
</div>
</div>
</div>
All looks good when focusing on the element. However, when I unfocus there is a flash of black top border for some reason. Why is this happeneing?
I tried to remove the transition but it is still there. How can I make it transition back to the light grey color it was without the top border flashing black in between?
This is due to the border-top property on input.my-input:focus being set to none. Removing that and adjusting the negative margin on input:focus ~ .floating-label should fix it:
Edit: In response to OP's comment - changing the color of the border-top property will resolve the issue:
.paddings{
padding: 5rem;
}
input.my-input:focus {
box-shadow: none;
border: thin solid rgba(0, 100, 173, 0.5);
border-top: whitesmoke;
}
.floating-label{
color: rgb(80 80 80);
pointer-events: none;
position: absolute;
left: 2.5rem;
top: 0.5rem;
transition: 0.2s ease all;
}
input:focus ~ .floating-label {
color: rgb(40 40 40);
font-size: 0.85rem;
top: -0.65rem;
left: 2rem;
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#3.3.7/dist/css/bootstrap.min.css">
<div class="row paddings">
<div class="col-md-12">
<div>
<input class="form-control my-input" type="text">
<span class="floating-label">Search</span>
</div>
</div>
</div>

CSS element automatically closing when active / selected

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?
https://codepen.io/richag_ff/pen/bGayzeP
<div class="searchbar">
#Html.TextBox("SearchText", ViewBag.SearchText as String, new { #class = "search_input", placeholder = "Search by part or reference" })
<i class="fa fa-search search_icon_i"></i>
</div>
.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;
}
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:
Add a hidden checkbox
.searchbar is a <label>
.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' class="searchbar">
<input id='search' name='search' type='search'>
<b class="search-icon"><i class="fa fa-search fa-lg"></i></b>
</label>
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" class="inputmain" placeholder="Send out a leprechaun to go search what u are looking for..." value="" />
</div>

Flyout search box with css

I want to implement search box that appears on button click and hides on click somewhere outside. I'm trying to implement this with css.
I have next html:
<div tabindex="0" class="search">
<div id="mobileSearch" class="search-by-name form-group ember-view">
<div tabindex="0" role="button" id="ember415" class="ember-power-select-trigger ember-power-select-typeahead-trigger ember-basic-dropdown-trigger ember-view">
<input type="search" id="ember-power-select-typeahead-input-ember410" class="ember-power-select-typeahead-input ember-power-select-search-input">
</div>
<div id="ember-basic-dropdown-content-ember410" style="display: none;" class="ember-basic-dropdown-content-placeholder"></div>
</div>
<div type="button" class="btn mobile-search-button"></div>
</div>
And scss:
.navbar {
> .container-fluid {
> .navbar-header {
> .search {
> #mobileSearch {
width: 42px;
height: 42px;
display: inline;
> div {
margin-top: 15px;
display: inline;
height: 42px;
position: absolute;
min-width: 0;
max-width: 0;
margin-left: 42px;
padding: 0;
border: none;
-webkit-transition: all 0.6s ease-in-out;
-moz-transition: all 0.6s ease-in-out;
-o-transition: all 0.6s ease-in-out;
transition: all 0.6s ease-in-out;
}
}
}
> .search:focus {
outline: none;
}
.search > #mobileSearch > div:focus,
> .search:focus > #mobileSearch > div {
min-width: 220px;
max-width: 220px;
padding: 2px 16px 2px 8px;
margin-left: -178px;
border: 1px solid #ccc;
}
.mobile-search-button {
width: 42px;
height: 42px;
margin-top: 15px;
background-color: transparent;
background-image: url('/assets/search-128.png');
background-size: cover;
}
}
}
}
When user clicks on button search box appears, and when he clicks outside it hides. This part works OK. But when user move focus to input field search box also hides. I understand that issue was related to search box structure (div with div with div with input) but I can't change last layers (div with input) because it is plugin's component.
I would prefer a solution without Javascript.
try
.search:focus-within
it will work with .search and all child elements

Does :focus work with specificity as :hover does?

Here is my problem. I want the input-group-addon that holds an icon (search icon, calendar icon, etc) to inherit the hover, focus, and active states of its input field by specificity. I have it working for hover but for some reason specificity is ignoring the focus state. I thought it was a conflicting css directive in my code but I isolated the problem in CODEPEN and it does it there as well.
In summary, I want the input group addon border to change to yellow seamlessly with its input field when I focus on it (tab or click), as it does when I hover on it.
My HTML:
<div class="input-group controls">
<input type="text" class="form-control" placeholder="Search by Name" />
<span class="input-group-addon right search"></span>
</div>
My CSS (Use Chrome if possible. I didn't include here the corssbrowser stuff to make it simpler to read) Also, this is originally built on SCSS:
.mar40 {
margin: 40px auto;
}
.form-control {
border-width: 2px;
border-color: #8f8f8f;
-webkit-box-shadow: none;
box-shadow: none;
color: #bbbbbb;
-webkit-border-radius: 34px;
-moz-border-radius: 34px;
-ms-border-radius: 34px;
border-radius: 34px;
background: #211E1E;
}
.form-control:focus,
.form-control:hover {
border-color: rgba(248, 151, 29, 0.77);
-webkit-box-shadow: none;
box-shadow: none;
outline: none;
transition: all 1s ease;
}
.form-control .input-group-addon {
background: #8f8f8f;
border-color: #555555;
border-width: 2px;
}
.controls .input-group-addon.right.search {
background: #30373e;
border: 2px solid #8f8f8f;
color: #bbbbbb;
border-left: none;
border-radius: 0px 20px 20px 0;
padding: 4px 10px;
min-width: 0;
}
.controls .input-group-addon.right.search:before {
content: "\f4a4";
font-family: 'Ionicons';
font-size: 16px;
}
.controls:focus .input-group-addon.right,
.controls:hover .input-group-addon.right,
.controls:active .input-group-addon.right {
border: 2px solid rgba(248, 151, 29, 0.77) !important;
border-left: none !important;
transition: all 1s ease;
}
.controls:focus .input-group-addon.right:before,
.controls:hover .input-group-addon.right:before,
.controls:active .input-group-addon.right:before {
color: rgba(248, 151, 29, 0.77);
transition: all 1s ease;
}
Desired effect illustration on hover/focus/active
This is what I am getting on focus
And the handy dandy CODEPEN
Thanks!
:focus applies for the input and not the parent container and so your selector group should be as follows. (Note the changed selector in the first line)
.form-control:focus + .input-group-addon.right,
.controls:hover .input-group-addon.right,
.controls:active .input-group-addon.right {
border: 2px solid rgba(248, 151, 29, 0.77) !important;
border-left: none !important;
transition: all 1s ease;
}
As far as I know, when you :hover the child you are also indirectly hovering on the parent and so the .controls:hover .input-group-addon.right also works when .form-control:hover is applicable. Thus both the .form-control and .input-group-addon.right get the border.
But when you focus on the .form-control, the focus selector applies only to the input and doesn't get applied to its container. Thus only the .form-control gets the border and not the .input-group-addon. So, the selector must be changed to style the .input-group-addon based on the input and not the container's focus.
CodePen Demo

Grouping css tag using pseudo class before (Hover)

I am working on Grouping CSS Selector (Hover). I have two text boxes the first one is Username and second one is Password.
When I hover these text field's the icon background has changing the color using transistion.
Here is the HTML Code
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12 login-panel-padng">
<span class="icon-user">
<input type="text" class="txt-padding login-panel-usr-name" placeholder="Username" />
</span>
</div>
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12 login-panel-padng">
<span class="icon-password">
<input class="txt-padding login-panel-usr-name" id="txt_pwd" type="password" placeholder="Password"/>
</span>
</div>
Here is the code.
.icon-user::before {
font-family: FontAwesome;
content:"\f007";
font-size: 18px;
position: absolute;
border-right: 1px solid lightBlue;
border-top-left-radius: 10px;
height: 40px;
padding: 10px 15px 15px 15px;
-webkit-transition : background 500ms ease-out;
-moz-transition : background 500ms ease-out;
-o-transition : background 500ms ease-out;
}
.icon-password::before {
font-family: FontAwesome;
content:"\f084";
font-size: 18px;
position: absolute;
border-right: 1px solid lightBlue;
border-top-left-radius: 10px;
height: 40px;
padding: 10px 15px 15px 15px;
-webkit-transition : background 500ms ease-out;
-moz-transition : background 500ms ease-out;
-o-transition : background 500ms ease-out;
}
.icon-user .icon-password:hover:after {
background-color: lightBlue;
border-top-left-radius: 10px;
border: 1px solid #336699;
}
For the Hover I want to use both icon-user and icon-password class tags. So I can reduce the Number of code line.
Here is the jsfiddle Link
Kindly help me for this question.
Cheers
Mahadevan
Thanks for the reply. I got the solution for the above question.
.icon-user:hover::before, .icon-password:hover::before{
background-color: lightBlue;
border-top-left-radius: 10px;
border: 1px solid #336699;
}
You have to call all the class like above example. Then the Hover effect will come.
Cheers,
Mahadevan
If you want to group them, why not use the same class on both,
...
<span class="inputIcon icon-user">
...
</span>
...
<span class="inputIcon icon-password">
...
</span>
...
and then,
.inputIcon:hover::before { ... }