I want to make a simple input that when you focus on it a nice border appears from the bottom center of it with some transition:
<form method="POST" action="/admin/add-product" class="add-product">
<div class="form-input">
<label for="title">title</label>
<input type="text" name="title" id="title" placeholder="title">
</div>
<button className="btn btn-green">Add product</button>
</form>
\* some basic styling for the form *\
.add-product {
width: 500px;
max-width: 95%;
margin: 3rem auto;
padding: 2rem;
}
\* .form-input contains the input and the label *\
.form-input {
width: 100%;
position: relative;
}
.form-input input,
.form-input label {
display: block;
width: 100%;
margin-bottom: 1rem;
}
.form-input input {
height: 2rem;
background: transparent;
border: transparent;
}
\* the ::after *\
.form-input::after {
content: "";
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
height: 2px;
width: 0%;
background-color: var(--green);
transition: width 0.6s;
}
\* this where I think I made a mistake these changes are not applied to ::after at :focus *\
.form-input input:focus + ::after {
width: 100%;
}
I expected to see the ::after element's width to change but it doesn't so I think there is a mistake in selecting this way .form-input input:focus + ::after; even though I think there is no
CSS does have a :focus-within pseudo class solution for this:
.form-input:focus-within::after { width: 100%; }
It's supported in all major browsers.
.form-input::after matches the pseudo-element that appears after the content of any .form-input element.
.form-input input:focus + ::after matches the pseudo-element that appears after the content of the next sibling of any focused input that is a descendant of .form-input.
Unless you have HTML like:
<div class="form-input">
<input>
<div class="form-input"></div>
</div>
… that isn't going to match anything.
You can't select the parent element's ::after based on the focus state of a child element. CSS doesn't have a parent selector.
You'd need to use JS for this.
Related
I've put together this pen: https://codepen.io/NanoSpicer/pen/YzQgQVd
The idea is that using the sibling selector I want to style a certain element when the element before the one I want to style is focused.
It works great with input elements, but it fails miserably when using elements with contenteditable attribute:
.container,
form {
width: 30%;
display: flex;
flex-direction: column;
gap: 10px;
}
div[contenteditable="true"]::before {
text-color: gray;
opacity: 0.6;
content: attr(placeholder);
}
div[contenteditable="true"],
input {
/* remove system hightlighting*/
outline-style: none;
box-shadow: none;
min-height: 40px;
appearance: none;
border: 3px solid;
border-color: gray;
border-radius: 6px;
}
div[contenteditable="true"]:focus,
input:focus {
border-color: blue;
}
*:focus+* {
border-color: red;
}
<form>
<input placeholder="first" id="first" type="text">
<input placeholder="second" id="second" type="password">
</form>
<div class="container">
<div contenteditable="true" placeholder="first"></div>
<div contenteditable="true" placeholder="second"></div>
</div>
Note: Tested on Firefox and Chrome.
That is very strange. Probably a bug.
This workaround is good for Firefox and Chrome on PC. Didn't test other browsers / platforms.
[contenteditable]:focus + * {
border-color:green;
}
Just like you did for in the beginning of your CSS, be more specific to indicate you want to react with the contenteditable attribute.
By default, div are not editable, so not focusable, so you have to be a bit more specific with this.
To make this work, you should edit the last CSS property to add the second selector line like I wrote here :
*:focus + *,
div[contenteditable="true"]:focus + div {
border-color: red;
}
or if you want to make it more generic:
*:focus + *,
*[contenteditable="true"]:focus + * {
border-color: red;
}
I need your help.
Is there a way to change the border color of the parent div, when the child select box is either hovered, active or focused?
<style type="text/css">
div.select select:hover,
div.select select:focus,
div.select select:active {
background: rgb(255,255,196);
border-color: rgb(85,85,85);
}
</style>
<div class="select" style="background: #FFF; width: 200px; border: 1px solid rgb(170,170,170);">
<select style="width: 100%; border:0px; outline:0px; padding: 2px;">
<option value="Sal">Sal</option>
<option value="Awesome">Awesome!</option>
</select>
</div>
An alternative solution would be to use the focus-within selector: https://css-tricks.com/almanac/selectors/f/focus-within/
As we know, there is no CSS parent selector, but if all you need to do is change border-color (and possibly background) on :hover, you can use a pseudo element & some positioning + z-index hacks to do it. Here's an example with comments inline
div.select {
height: 50px;
background: #FFF;
width: 200px;
position: relative;
/* to position the pseudo element */
z-index: 1;
/* HACK: to make sure it doesn't affect anything globally. */
/* Increase this value if the element is not visible */
/* or you have z-index set in your code */
}
.select-wrap::after {
content: ' ';
position: absolute;
top: -1px;
/* for outside border */
left: -1px;
right: -1px;
bottom: -1px;
background: #eee;
border: 1px solid transparent;
pointer-events: none;
/* to make sure hovering on the background doesn't trigger color change */
}
.select-wrap:hover::after {
background: yellow;
border-color: black;
}
select {
width: 100%;
border: 0px;
outline: 0px;
padding: 2px;
position: relative;
z-index: 10;
/* HACK: Can be any number more than the :after element's z-index. */
/* As the parent has a z-index, it won't affect anything globally */
}
<div class="select" style="">
<div class='select-wrap'>
<select>
<option value="Sal">Sal</option>
<option value="Awesome">Awesome!</option>
</select>
</div>
</div>
Codepen link: https://codepen.io/palash/pen/wpRVQV
Also, note that pseudo elements do not work with <select>, hence the need for the 'select-wrap' <span>
I'm trying to create a custom component using only CSS and HTML.
The behavior of the component will be like: when the input is selected (has focus) another container is open.
The problem is when the container is opened the input lose focus and the container is closed on first click :(
So How can I have that input focus focused when I'm on the opened container focused ?
<div class="block">
<label>Field</label>
<input type="text" tabindex="-1"/>
<div tabindex="-1" class="infront">
Keep this bastard open.<br/>
<br/>
while clicking on this div
</div>
</div>
CSS
.block{
position: relative;
display: inline-block;
margin: 50px;
}
.infront{display: none;}
.block input[type="text"]:focus ~ .infront {
display: block;
position: absolute;
top:100%;
width: 80%;
right: 0;
background: #ccc;
opacity:0.8;
}
Fiddle:
You need to take care of the state of .infront container states as well.
Update your CSS to this
.block input[type="text"]:focus ~ .infront
, .infront:hover
, .infront:active
, .infront:focus {
display: block;
position: absolute;
top:100%;
width: 80%;
right: 0;
background: #ccc;
opacity:0.8;
}
I think you can not do it only with HTML and CSS. You will need some jquery code like this:
$(.block input[type=text]).on('focus', function(e) {
$('.infront').show();
});
I have the following HTML structure:
<span id="span_pagination_text_input">
<input type="text" class="form-control" id="pagination_text_input" name="pagination_text_input"/>
...
</span>
And Following CSS:
span#span_pagination_text_input{
position:relative;
}
span#span_pagination_text_input > input#pagination_text_input{
left: -11px;
position: absolute;
top: -35px;
width: 57px;
z-index: 10;
display:none;
text-align:center
}
span#span_pagination_text_input:hover > input#pagination_text_input{
display:block;
}
At this time when visitors hover on my span, I will show the input field which is hidden by default.
How I can focus on input children of span when I show that with CSS?
I know about jQuery but at this time I am looking for a CSS solution.
You can achieve that by using tabindex which HTML5 allows in all elements now along with the :focus, to fake the display:none use border:0
input {
border: 0;
width: 57px;
z-index: 10;
text-align: center
}
span:focus input {
border: 5px solid red;
transition: border .1s
}
input:focus {
border: 5px solid green;
}
<span tabindex="1" id="span_pagination_text_input">
Click me
<input type="text" class="form-control" id="pagination_text_input" name="pagination_text_input" />
</span>
I don't think that it is possible with only css. You can try javascript
document.getElementById("IdOfInput").focus();
:-)
I have the following mark-up using the bootstrap framework.
<div class="col-md-4">
<div class="custom-container">
<img class="center-block img-responsive img-circle invite-contact-trybe" src="{$img}" alt="Contact Image">
<input class="invite-contact-checkbox" type="checkbox">
</div>
</div>
I would like to achieve the following:
Is there anyway to do this using CSS?
I would obviously need 3 states:
Initial:
.custom-container input[type=checkbox]{}
Some form of hover state:
.custom-container input[type=checkbox]:hover{}
When it is checked:
.custom-container input[type=checkbox]:checked{}
Can anyone suggest a solution?
Background image checkbox replacement
Let's create this
This is a very simple example using a :before pseudo element as well as :checked and :hover states.
With this clean HTML
<input type="checkbox" id="inputOne" />
<label for="inputOne"></label>
Note the matching for and id attributes, this attaches the label to the checkbox. Also, the order of elements is very important; the label must come after the input so we can style with input:checked
As well as this Basic CSS
The checkbox is hidden with display: none and all interaction is done with the label
The :after pseudo element is given a unicode tick (\2714) but this could also be ticked with a background image.
The jagged edge caused by the border-radius can be softened by a matching color box-shadow. The inside edge of the border looks fine when the background image is not a solid block of color.
The transition: all 0.4s creates a smooth fade in / out for the border.
I have added more guidance in CSS comments.
Complete Example
input[type=checkbox] {
display: none;
}
/*
- Style each label that is directly after the input
- position: relative; will ensure that any position: absolute children will position themselves in relation to it
*/
input[type=checkbox] + label {
position: relative;
background: url(http://i.stack.imgur.com/ocgp1.jpg) no-repeat;
height: 50px;
width: 50px;
display: block;
border-radius: 50%;
transition: box-shadow 0.4s, border 0.4s;
border: solid 5px #FFF;
box-shadow: 0 0 1px #FFF;/* Soften the jagged edge */
cursor: pointer;
}
/* Provide a border when hovered and when the checkbox before it is checked */
input[type=checkbox] + label:hover,
input[type=checkbox]:checked + label {
border: solid 5px #F00;
box-shadow: 0 0 1px #F00;
/* Soften the jagged edge */
}
/*
- Create a pseudo element :after when checked and provide a tick
- Center the content
*/
input[type=checkbox]:checked + label:after {
content: '\2714';
/*content is required, though it can be empty - content: '';*/
height: 1em;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
margin: auto;
color: #F00;
line-height: 1;
font-size: 18px;
text-align: center;
}
<input type="checkbox" id="inputOne" />
<label for="inputOne"></label>