CSS solution to make drop-down element visible while focused - css

I'm trying to figure out if there is any pure CSS solution to keep a drop-down element open while the input field of that element is focused? Here is an example:
div {
width: 300px;
line-height: 50px;
text-align: center;
background: #e8e8e8;
border: 1px solid #666;
}
div:hover form {
display: block;
}
form {
display: none;
padding: 0 15px;
}
<div>Hover Me
<form class="search">
<input type="search" placeholder="What are you looking for?" autofocus>
<input type="button" value="Search!">
</form>
</div>
The idea is to keep the form visible when the search field is focused. Because when a user starts typing the search inquiry and the mouse move out of the hover zone, the form hides, and that's very annoying.
Side-question: Is it possible to focus via CSS search input element each time a <div> is hovered?

The solution has been already proposed, but lacks browser support:
9.4. The Generalized Input Focus Pseudo-class: :focus-within
The :focus-within pseudo-class applies to elements for which the
:focus pseudo class applies.
An element also matches :focus-within if one of its
shadow-including descendants matches :focus.
div {
width: 300px;
line-height: 50px;
text-align: center;
background: #e8e8e8;
border: 1px solid #666;
}
div:hover form, div:focus-within form {
display: block;
}
form {
display: none;
padding: 0 15px;
}
<div tabindex="-1">Hover Me
<form class="search">
<input type="search" placeholder="What are you looking for?" autofocus>
<input type="button" value="Search!">
</form>
</div>
Meanwhile, you can use a polyfill:
div {
width: 300px;
line-height: 50px;
text-align: center;
background: #e8e8e8;
border: 1px solid #666;
}
div:hover form, div.focus-within form {
display: block;
}
form {
display: none;
padding: 0 15px;
}
<script src="https://gist.githubusercontent.com/aFarkas/a7e0d85450f323d5e164/raw/"></script>
<div tabindex="-1">Hover Me
<form class="search">
<input type="search" placeholder="What are you looking for?" autofocus>
<input type="button" value="Search!">
</form>
</div>

Wait. There's actually a pure CSS solution. But there is a drawback — it only works with just one <input> tag, and no <form> tag, like this:
div {
width: 300px;
line-height: 50px;
text-align: center;
background: #e8e8e8;
border: 1px solid #666;
padding: 0.5%;
}
input {
display: none;
margin: auto;
}
div:hover input {
display: block;
}
input:focus {
display: block !important
}
<div>Hover Me
<input type="search" placeholder="What are you looking for?">
</form>
</div>
However, you can just make the user search the form by pressing Enter on the keyboard. Unfortunately, this requires JavaScript, which defeats the whole purpose of this post.
I've also noticed that your placeholder text doesn't really work properly, since the text "Search" is still there. There are two solutions to this — use JavaScript to fix it, or change the 'type' of the input tag to "text".

Related

How to separate label text respective to div?

I have a label defined where one half needs to be at left side and the other half of text needs to be on right side. How can I solve this so that the other half is pulled right?
I have added margin-right to get the text to pull at right but it's not consistent for other divs.
<div class="radio">
<input class="radio-test" type="radio" value="3" checked="checked" name="test[id]" id="test_id">
<label class="radio-label" for="test_id_1">
Test of $12.0
<span class="test-cost">Free</span>
</label>
<hr class="test-hr">
<p class="test-message"></p><p>- First test message</p><p></p>
</div>
Expected Result:
Current Result:
How can I make text in above image i.e. 'Free' to appear on the right most side as shown on expected result? Also make it always consistent on other div such that the space from div is same across.
Here is a complete working example with JsBin: https://jsbin.com/yafesuyola/1/edit?html,css,output
It uses flexbox with justify-content: space-between. I also added a div around the label and the input to keep them on the same line with 100% width.
<div class="radio">
<div class="radio-and-label">
<input class="radio-test" type="radio" value="3" checked="checked" name="test[id]" id="test_id">
<label class="radio-label" for="test_id_1">
Test of $12.0
<span class="test-cost">Free</span>
</label>
</div>
<hr class="test-hr">
<p class="test-message"></p><p>- First test message</p><p></p>
</div>
.radio {
border: 2px solid #33c;
border-radius: 5px;
padding: 10px;
background: #e0eeff;
color: #33c;
font-weight: bold;
}
.radio-and-label {
display: flex;
}
.radio-label {
width: 100%;
display: flex;
justify-content: space-between;
}
.test-cost {
text-align: right;
}
.test-hr {
display: block;
height: 1px;
border: 0;
border-top: 1px solid #ccc;
margin: 1em 0;
padding: 0;
}
Hope that helps!
Clip the element to always be pinned to top right of the element?
.radio {
position: relative;
}
.test-cost {
position: absolute;
top: 2px;
right: 2px; // or whatever px/rem/etc value that fits your need
}

Custom checkbox and radio button not support in all browser

I used custom checkbox and radio button for my project using :before and :after, but this work only in "Google Chrome" and not supported in other browsers, Is any trick that's why it should look same in all browser, I don't want to use label after checkbox or radio button.
CSS is here:
FIDDLE ( For example )
My actual radio button looks like this :
Google Chrome:
Firefox:
IE:
Pseudo Elements like :before and :after add content before and after the content of an element. Checkbox and Radio buttons do not have content, so they don't support before and after pseudo elements. Chrome is ' special ' , but the normal behavior is the one from FF and IE.
Furthermore checkbox and radio are browser default elements. They are very hard to change and not supposed to be changed.
Although you said you don't want to add a label, that's the way to go. Add it with position absolute to put it on top of the radiobutton/checkbox like in the example below
body {
padding: 50px;
}
input[type='radio'] {
margin: 0;
height: 13px;
width: 13px;
margin-top: 2px;
position: relative;
}
div.wrapper {
position: relative;
}
input[type='radio'] + label {
content: '';
display: inline-block;
width: 13px;
height: 13px;
border: none;
position: absolute;
left: 0;
top: 1px;
background: gray url("../images/i-radio-empty.png") no-repeat 0 0;
}
input[type='radio']:checked + label {
width: 13px;
height: 13px;
background: red url("../images/i-radio-checked.png") no-repeat 0 0;
}
<div class="wrapper">
<input type="radio" name="gender" value="male" id="male"> Male
<label for="male"></label>
</div>
<div class="wrapper">
<input type="radio" name="gender" value="female" id="female"> Female
<label for="female"></label>
</div>
<div class="wrapper">
<input type="radio" name="gender" value="other" id="other"> Other
<label for="other"></label>
</div>
Mihai T's solution isn't bad, but not checking checkbox when cliking on text can be really anoying. I personally hate it :)
Though it is true that radio and chekbox does not support pseudo elemens :before and :after but label does. So you can have normal label with text and pseudo element :before with position: absolute.
div.wrapper {
position: relative;
display: inline-block;
margin-right: 10px;
}
input[type='radio'] {
display: none;
}
input[type='radio'] + label {
padding-left: 20px;
}
input[type='radio'] + label:before {
content: '';
width: 13px;
height: 13px;
position: absolute;
left: 0;
top: 1px;
background: #FFF;
border: 1px solid #999;
border-radius: 50%;
cursor: pointer;
box-sizing: border-box;
}
input[type='radio']:checked + label:before {
background: #000;
border: 4px solid #F9CC55;
}
<div class="wrapper">
<input type="radio" name="gender" value="male" id="male">
<label for="male">Create Tabs Group</label>
</div>
<div class="wrapper">
<input type="radio" name="gender" value="female" id="female">
<label for="female">Update Existing Tabs Group</label>
</div>

My pseudo-class :not with input element isn't working correctly

I'm trying to use the CSS3 input pseudo-class, but it's not working. These styles are being applied to my inputs inside the .import-holder div. They should apply to everything except the inputs.
.content .import-holder:not(input){
width: 500px;
height: 100px;
border: 2px solid white;
margin-left: auto;
margin-right: auto;
text-align: center;
}
<div class="container import-holder">
<form method="POST" action="">
<fieldset>
<legend>Import Excel</legend>
<input name="filename" type="file">
<input type="submit" value="Import">
</fieldset>
</form>
</div>
.content .import-holder:not(input) will select descendants of elements with a content class, that are not input elements, and have an import-holder class.
You appear to want .content .import-holder *:not(input) (note the space!), which looks for elements that are not an input and descendants of .import-holder elements.
Here is a simplified example of what the selector works on.
* {
color: red;
}
.import-holder *:not(input) {
color: blue;
}
<div class="import-holder">
<h1>Heading</h1>
<p>Paragraph</p>
<input type="text" value="Input" />
<h2>Another heading</h2>
<p>Paragraph with a <span>span</span> in it.</p>
</div>
You can achieve this by specifying the input type element, you want to exclude from styling.
Bellow code will work as your need.
.content .import-holder input:not([type='text']):not([type='submit']) {
width: 500px;
height: 100px;
border: 2px solid white;
margin-left: auto;
margin-right: auto;
text-align: center;
}

CSS layout - what is causing additional space

I have created the following jsFiddle to demonstrate my problem (or lack of understanding more like)
http://jsfiddle.net/gRCS6/
And Code here
<div id="scoreboard"></div>
<canvas id="game">
Your browser does not support canvas.
</canvas>
<div id="controls">
<button type="submit" id="newGame">New</button>
<button type="submit" id="pause">Pause</button>
<button type="submit" id="help">Help</button>
</div>
#game {
border: 1px solid #000000;
background-color:#333333;
width: 250px;
margin:0px;
}
#scoreboard {
border: 1px solid #000000;
background-color:#333333;
color: orange;
width: 250px;
height: 40px;
font:36px arial,sans-serif;
text-align: right;;
}
#controls {
margin-top: -5px;
padding:0px;
}
button {
border: 1px solid #000000;
margin-left:0px;
background-color:#333333;
color: orange;
width:82px;
height: 40px;
}
Why does the div with id "controls" need a margin-top of -5px to make it touch the canvas above it?
What is taking up that 5 pixels?
What is stopping the 3 buttons from being next to each other with no space between them?
"Why does the div with id "controls" need a margin-top of -5px to make it touch the canvas above it?"
Like ralph.m pointed out, can be fixed by adding
canvas {
display: block;
}
"What is stopping the 3 buttons from being next to each other with no space between them?"
Well, since there are spaces (the character ' ') between the button elements in the html code you will see those spaces between the buttons when the page is displayed. You can either remove the spaces:
<button type="submit" id="newGame">New</button><button type="submit" id="pause">Pause</button><button type="submit" id="help">Help</button>
Instead of
<button type="submit" id="newGame">New</button>
<button type="submit" id="pause">Pause</button>
<button type="submit" id="help">Help</button>
Or you can try to fix it with css styling, for example by adding float: left; to the button selector.
The canvas element is display: inline (or is it inline-block?) by default, which means by default there is a gap at the bottom so that it will align with the baseline of any text beside it.
You can change this by setting the canvas to display: block or vertical-align: bottom.
It's a similar problem with the buttons, which are display: inline-block, meaning that there is space between them (as there is a natural space between words). As mentioned in the chosen answer, removing the white space is an option, but a more elegant solution is as follows:
#controls {word-spacing: -2em; display: table; width: 100%;}
button {word-spacing:0;}
Answer to Q1: Check this topic. Different browsers have different algorythm, so you should some extra parameters for body css.
body
{
margin: 0;
padding: 0;
}
Answer to Q2: Avoid using to close button tab. is not necessary, if you remove it, the margin between buttons will disappear. http://jsfiddle.net/gRCS6/5/
<button type="submit" class="button">New
<button type="submit" class="button">Pause
<button type="submit" class="button">Help
Another way to fix the issue is to use absolute positioning to define the exact placement of your controls div. Then you have to ability to define the exact alignment of the buttons regardless of display: inline-block; or display: block; commands.
http://jsfiddle.net/gRCS6/34/
#game {
border: 1px solid #000000;
background-color:#333333;
width: 250px;
height: 120px;
margin:0px;
position: absolute;
}
#scoreboard {
border: 1px solid #000000;
background-color:#333333;
color: orange;
width: 250px;
height: 40px;
font:36px arial,sans-serif;
text-align: right;
}
#controls {
position: absolute;
top: 172px;
margin-top: 0px;
padding: 0px;
}
button {
border: 1px solid #000000;
margin:0px;
background-color:#333333;
color: orange;
width:81.5px;
height: 40px;
}

Is there a way to display HTML5 required pop-up when hiding the input?

I have a checkbox that I am styling by hiding the input and targetting a span nested in a label. See http://jsfiddle.net/rz6np/
HTML:
<input id="confirm" type="checkbox" name="confirm" value="1" required="required" />
<label for="confirm"><span>+</span>Confirm</label>
CSS:
input[type="checkbox"] {
display: none;
}
form input[type="checkbox"] + label span {
display: inline-block;
width: 16px;
height: 16px;
margin: 1px 10px 5px 0;
vertical-align: middle;
cursor: pointer;
border: 1px solid grey;
color: #fff;
font-size: 15px;
padding: 2px 2px;
}
input[type="checkbox"]:checked + label span {
color: #000;
}
As the input is hidden it means the html5 required pop-up doesn't display. Is there a way to force it to display?
Assuming the design looks like this or similar to this, don't use display: none. The styled checkbox is large enough to cover it, so just position it over the checkbox with position relative or absolute, and appropriate z-index.
If it won't cover it completely, you could still get away with using visibility:hidden on the checkbox. I still see the popup in Firefox even though the field is invisible, but you'll need to check other browsers and how they behave.
input and span should be inside the label:
<label for="confirm">
<input id="confirm" type="checkbox" name="confirm" value="1" required="required" />
<span>+</span>
Confirm
</label>
Then on input:
label {
position: relative;
}
label > input[type="checkbox"] {
opacity: 0;
position: absolute;
top: 0;
left: 0;
}

Resources