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();
});
Related
I have a button with span included which then has a pseudo-selector, :before applied to it in some cases.
When the element (button) receives focus, the :before is also receiving focus and the focus ring, resulting in something like this:
While I'd like to keep the focus ring on the button itself, I'm having a difficulty removing it from the contained :before element. See this JSFiddle:
https://jsfiddle.net/uhgsj6cp/3/
The HTML/CSS is fairly basic:
.btn {
width: 100px
}
.btn>span {
position: relative;
}
.btn>span:before {
display: block;
content: '•';
font-size: 32px;
position: absolute;
left: -13px;
top: -13px;
}
<button class='btn btn-default'>
<span>Text</span>
</button>
Reduce the line-height then hide the overflow:
.btn {
width: 100px
}
.btn>span {
position: relative;
}
.btn>span:before {
/*display: block; not need*/
content: '•';
font-size: 32px;
position: absolute;
left: -13px;
top: 0;
overflow:hidden;
line-height:0.4;
}
<button class='btn btn-default'>
<span>Text</span>
</button>
I was able to ALMOST remove that artifact outline with adjusting line-height and top on the pseudo element.
However, you could also try using the HTML • to produce the bullet within the button.
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();
:-)
Just been playing about with pointer-events property in CSS.
I have a div that I want to be invisible to all mouse events, except for :hover.
So all click commands go through the div to the one below it, but the div can report whether the mouse is above it or not still.
Can anyone tell me if this can be done?
HTML:
<div class="layer" style="z-index:20; pointer-events:none;">Top layer</div>
<div class="layer" style="z-index:10;">Bottom layer</div>
CSS:
.layer {
position:absolute;
top:0px;
left:0px;
height:400px;
width:400px;
}
Hover only. It is very easy. No JS... Prevent link default action too.
a:hover {
color: red;
}
a:active {
pointer-events: none;
}
Link here
Edit:
supported in IE 11 and above
http://caniuse.com/#search=pointer-events
"Stealing" Xanco's answer but without that ugly, ugly jQuery.
Snippet: Notice DIVs are in reverse order
.layer {
position: absolute;
top: 0px;
left: 0px;
height: 400px;
width: 400px;
}
#bottomlayer {
z-index: 10
}
#toplayer {
z-index: 20;
pointer-events: none;
background-color: white;
display: none
}
#bottomlayer:hover~#toplayer {
display: block
}
<div id="bottomlayer" class="layer">Bottom layer</div>
<div id="toplayer" class="layer">Top layer</div>
I don't think it's possible to achieve your aims in CSS alone. However, as other contributors have mentioned, it's easy enough to do in JQuery. Here's how I've done it:
HTML
<div
id="toplayer"
class="layer"
style="
z-index: 20;
pointer-events: none;
background-color: white;
display: none;
"
>
Top layer
</div>
<div id="bottomlayer" class="layer" style="z-index: 10">Bottom layer</div>
CSS (unchanged)
.layer {
position:absolute;
top:0px;
left:0px;
height:400px;
width:400px;
}
JQuery
$(document).ready(function(){
$("#bottomlayer").hover(
function() {
$("#toplayer").css("display", "block");
},
function() {
$("#toplayer").css("display", "none");
}
);
});
Here's the JSFiddle: http://www.jsfiddle.net/ReZ9M
You can also detect hover on different element and apply styles to it's child, or using other css selectors like adjacent children, etc.
It depends on your case though.
On parent element hover. I did this:
.child {
pointer-events: none;
background-color: white;
}
.parent:hover > .child {
background-color: black;
}
Pure CSS solution to your request (the opacity property is there just to illustrate the need for the transitions):
.hoverOnly:hover {
pointer-events: none;
opacity: 0.1;
transition-delay: 0s;
}
.hoverOnly {
transition: ,5s all;
opacity: 0.75;
transition-delay: 2s;
}
What it does:
When the mouse enters the box, it triggers the :hover state. However, in that state, the pointer-events are disabled.
But if you do not set the transitions timers, the div will cancel the hover state when the mouse moves; the hover state will flicker while the mouse is moving inside the element. You can perceive this by using the code above with the opacity properties.
Setting a delay to the transition out of the hover state fixes it. The 2s value can be tweaked to suit your needs.
Credits to transitions tweak: patad on this answer.
Just pure css, doesn't need jquery:
div:hover {pointer-events: none}
div {pointer-events: auto}
I use the :hover pseudo-element of an equal-sized parent/container to simulate a hover over my overlay div, then set the overlay's pointer-events to none to pass through clicks to elements below.
let button = document.getElementById('woohoo-button');
button.onclick = () => console.log('woohoo!');
let overlay = document.getElementById('overlay');
overlay.onclick = () => console.log(`Better change my pointer-events property back to 'none'`);
#container {
display: flex;
align-items: center;
justify-content: center;
position: relative;
background-color: green;
width: 300px;
height: 300px;
}
#overlay {
background-color: black;
width: 100%;
height: 100%;
opacity: 0;
z-index: 1;
/* Pass through clicks */
pointer-events: none;
}
/*
Set overlay hover style based on
:hover pseudo-element of its
container
*/
#container:hover #overlay {
opacity: 0.5;
}
#woohoo-button {
position: absolute;
width: 100px;
height: 100px;
background-color: red;
}
<div id="container">
<div id="overlay"></div>
<button id="woohoo-button">
Click Me
</button>
</div>
I want to have some css properties on input:focus so how can I do that?
My scenario is; when input get focus I want to show another div so how can I do that using only css?
On hover I can do that using ">" but on focus is not working and I don;t understand why :(.
so this is my code:
<div class="containerTooltipXxx">
<p class="paragraphClass">
Some text...<br /><input type="radio" /><br />More text...
</p><div class="blocks">
<label>Field</label> <input></input></div>
</div>
.containerTooltipXxx{
padding: 20px;
position: relative;
float: left;
display: inline-block;
border: 2px solid lime;
margin: 50px;
}
.paragraphClass{display: none;}
.containerTooltipXxx:hover > .paragraphClass, .containerTooltipXxx:focus > .paragraphClass{
display: block;
position: absolute;
top:-5px;
left: 50px;
background: red;
opacity:.9;
}
very important, the html hierarchy cannot be changed.
Thank you.
fiddle
using CSS you can only point to the next sibling elements. Here since the p tag is out of the parent div it is not possible using css.
I know that you don't want to change the HTML order but still I am showing it for example.
Moving p tag inside the div.blocks can do this with only CSS
.blocks input[type="text"]:focus ~ .paragraphClass {
display: block;
position: absolute;
top:-50px;
left: 50px;
background: #ccc;
opacity:.7;
}
DEMO
.containerTooltipXxx:hover > replace this by
.containerTooltipXxx:focus ~ .paragraphClass
{
display: block;
position: absolute;
top:-5px;
left: 50px;
background: red;
opacity:.9;
}
Your first hover selector is fine, but the second is wrong.
What you are doing with .containerTooltipXxx:focus > .paragraphClass, is selecting the immediate child .paragraphClass from a focused .containerTooltipXxx. Focus can only be used on things with input, and your container is just a div.
What you would need is a parent selector, but these are currently not available. They will be most likely in CSS4. http://www.w3.org/TR/selectors4/#subject
Currently, your best bet would be using javascript. Make an event listener for focus on the input box, and then programmatically apply a visible class to what you want to show.
Is there a way to hide the browse button and only leave the text box that works in all browsers?
I have tried setting the margins but they show up different in each browser
No, what you can do is a (ugly) workaround, but largely used
Create a normal input and a image
Create file input with opacity 0
When the user click on the image, you simulate a click on the file input
When file input change, you pass it's value to the normal input (so user can see the path)
Here you can see a full explanation, along with code:
http://www.quirksmode.org/dom/inputfile.html
You may just without making the element hidden, simply make it transparent by making its opacity to 0.
Making the input file hidden will make it STOP working. So DON'T DO THAT..
Here you can find an example for a transparent Browse operation;
.dropZoneOverlay, .FileUpload {
width: 283px;
height: 71px;
}
.dropZoneOverlay {
border: dotted 1px;
font-family: cursive;
color: #7066fb;
position: absolute;
top: 0px;
text-align: center;
}
.FileUpload {
opacity: 0;
position: relative;
z-index: 1;
}
<div class="dropZoneContainer">
<input type="file" id="drop_zone" class="FileUpload" accept=".jpg,.png,.gif" onchange="handleFileSelect(this) " />
<div class="dropZoneOverlay">Drag and drop your image <br />or<br />Click to add</div>
</div>
I find a good way of achieving this at Remove browse button from input=file.
The rationale behind this solution is that it creates a transparent input=file control and creates an layer visible to the user below the file control. The z-index of the input=file will be higher than the layer.
With this, it appears that the layer is the file control itself. But actually when you clicks on it, the input=file is the one clicked and the dialog for choosing file will appear.
Below code is very useful to hide default browse button and use custom instead:
(function($) {
$('input[type="file"]').bind('change', function() {
$("#img_text").html($('input[type="file"]').val());
});
})(jQuery)
.file-input-wrapper {
height: 30px;
margin: 2px;
overflow: hidden;
position: relative;
width: 118px;
background-color: #fff;
cursor: pointer;
}
.file-input-wrapper>input[type="file"] {
font-size: 40px;
position: absolute;
top: 0;
right: 0;
opacity: 0;
cursor: pointer;
}
.file-input-wrapper>.btn-file-input {
background-color: #494949;
border-radius: 4px;
color: #fff;
display: inline-block;
height: 34px;
margin: 0 0 0 -1px;
padding-left: 0;
width: 121px;
cursor: pointer;
}
.file-input-wrapper:hover>.btn-file-input {
//background-color: #494949;
}
#img_text {
float: right;
margin-right: -80px;
margin-top: -14px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
<div class="file-input-wrapper">
<button class="btn-file-input">SELECT FILES</button>
<input type="file" name="image" id="image" value="" />
</div>
<span id="img_text"></span>
</body>
Came across this question and didn't feel like any of the answers were clean. Here is my solution:
<label>
<span>Select file</span>
<input type="file" style="display: none">
</label>
When you click the label the select file dialog will open. No js needed to make it happen.
You can style the label to look like a button.
Here is an example using w3css and font awesome:
<label class="w3-button w3-blue w3-round">
<span><i class="fas fa-image"></i></span>
<input type="file" style="display: none" >
</label>
Of course you need to add an event listener to the input to detect a file was chosen.
HTML - InputFile component can be hide by writing some css.
Here I am adding an icon which overrides inputfile component.
<label class="custom-file-upload">
<InputFile OnChange="HandleFileSelected" />
<i class="fa fa-cloud-upload"></i> Upload
</label>
css-
<style>
input[type="file"] {
display: none;
}
.custom-file-upload {
border: 1px solid #ccc;
display: inline-block;
padding: 6px 12px;
cursor: pointer;
}
</style>
So I found this solution that is very easy to implement and gives a very clean GUI
put this in your HTML
<label class="att-each"><input type="file"></label>
and this in your CSS
label.att-each {
width: 68px;
height: 68px;
background: url("add-file.png") no-repeat;
text-indent: -9999px;
}
add-file.png can be any graphic you wish to show on the webpage. Clicking the graphic will launch the default file explorer.
Working Example: http://www.projectnaija.com/file-picker17.html
Just an additional hint for avoiding too much JavaScript here: if you add a label and style it like the "browse button" you want to have, you could place it over the real browse button provided by the browser or hide the button somehow differently. By clicking the label the browser behavior is to open the dialog to browse for the file (don't forget to add the "for" attribute on the label with value of the id of the file input field to make this happen). That way you can customize the button in almost any way you want.
In some cases, it might be necessary to add a second input field or text element to display the value of the file input and hide the input completely as described in other answers. Still the label would avoid to simulate the click on the text input button by JavaScript.
BTW a similar hack can be used for customizing checkboxes or radiobuttons. by adding a label for them, clicking the label causes to select the checkbox/radiobutton. The native checkbox/radiobutton then can be hidden somewere and be replaced by a custom element.
Just add negative text intent as so:
input[type=file] {
text-indent: -120px;
}
before:
after:
Oddly enough, this works for me (when I place inside a button tag).
.button {
position: relative;
input[type=file] {
color: transparent;
background-color: transparent;
position: absolute;
left: 0;
width: 100%;
height: 100%;
top: 0;
opacity: 0;
z-index: 100;
}
}
Only tested in Chrome (macOS Sierra).
the best way for it
<input type="file" id="file">
<label for="file" class="file-trigger">Click Me</label>
And you can style your "label" element
#file {
display: none;
}
.file-trigger {
/* your style */
}
As of 2022, modern browsers support file button pseudo selector. I was only struggling with Safari v16.1 which didn't work as expected and had to workaround button hiding (::-webkit-file-upload-button part).
input[type=file]::file-selector-button {
display: none;
}
input[type=file]::-webkit-file-upload-button {
display: block;
width: 0;
height: 0;
margin-left: -100%;
}
input[type=file]::-ms-browse {
display: none;
}
You may also use concise syntax:
::file-selector-button {
/* ... */
}
::-webkit-file-upload-button {
/* ... */
}
::-ms-browse {
/* ... */
}