On this website, I have images that you can hover over with your mouse and it will display two buttons. I want keyboard-only users to be able to tab through the site, so when they tab, the hoverable menu shows up. I've read a lot of solutions involving :focus and tabindex=0 but I can't seem to make it work. I have attempted to put tabindex=0 on the <a> tags to see if that would do it, but it doesn't. I believe the buttons will be tabbed through just fine if I could just get the hover menu to show up using the tab key. I might be missing something obvious, but I'm a beginner with all of these things. If it's not possible via CSS, can someone suggest a JS solution?
HTML
<div class="thumbnail thumbnail-medium-short">
<div class="nqspCover-container">
<img src="img/stuff.jpg" alt="Front cover" width="180px" height="233px">
<div class="overlay">
<div class="read-button">Read</div>
<div class="buy-button">Buy</div>
</div>
</div>
<div class="nqsp-caption">
<p>stuff</p>
</div>
</div>
CSS
.nqspCover-container {
position: relative;
width: 180px;
height: 233px;
margin: 0 auto;
}
.overlay {
position: absolute;
display: flex;
align-items: center;
justify-content: center;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,0);
transition: background 0.5s ease;
}
.nqspCover-container:hover .overlay {
background: rgba(0,0,0,.3);
}
.buy-button{
margin-top: 40px;
}
.read-button, .buy-button{
position: absolute;
width: 65px;
padding: 5px 15px;
border: solid 2px white;
opacity: 0;
transition: opacity .35s ease;
}
.read-button a, .buy-button a{
text-decoration: none;
text-align: center;
color: white;
}
.nqspCover-container:hover .read-button,
.nqspCover-container:hover .buy-button{
opacity: 1;
}
.read-button a:hover, .buy-button a:hover{
text-decoration: underline;
}
.read_button a:focus, .buy-button a:focus{
display: block;
}
Example of the hover menu I need to pop up when they tab to it (don't worry, the background img and buttons definitely won't look like that when it's done):
Only one element can have focus at a time, so you can not do this using :focus alone. That's what the :focus-within pseudo class was made to solve - but be aware of browser compatibility; MicroSofts two current browsers don't support it yet.
You'll need a JS solution or at least a polyfill for :focus-within
(FYI, div elements can't receive focus by default, so you'd need to start by adding the tabindex attribute. tabindex="0" is usually what you want to make an element focus-able in normal DOM order.)
I don't know if "focus" really does what I need it to do at all.
It does what the other pseudo classes do, too - no more or less: Identify/react to an element being in a specific state. What you do with it, or it's descendants/siblings, is up to you - by writing the selectors that target those elements, based on that parent/siblings state.
https://www.google.com/search?q=menu+with+focus-within gets you more detailed explanations & examples, f.e. http://www.scottohara.me/blog/2017/05/14/focus-within.html That one explains the topic pretty well, and also mentions a polyfill, https://allyjs.io/api/style/focus-within.html
Related
I’m trying to understand how bootstrap works, right now I’m not interested in how responsive functionality works, I’m only interested in how adding class to element will change its appearance.
For example adding class="checkbox-inline" to label like this
<label class="checkbox-inline">
will give you this shape
I’m trying to do the same thing using css and jQuery, but the problem is I need multiple divs to do this
<div class="buttoun-toggle">
<div id="line"></div>
<div id="circle"></div>
</div>
and with some css it will give me this shape
also I did the animation using jQuery (when you click it, it will move).
So what I did is so simple, create circle and square with rounded edge to make my button...
No the problem is this code is not reusable because I can't just use
<label class="buttoun-toggle">
to create this button again, and that mainly because it has three divs in it.
So what I need to know how Bootstrap has this code reusability and how I could do the same thing here, meaning how could I call class and all those div get called?
You would usually use pseudo-elements like, before and after to accomplish a composition of elements that are tied to one class:
.toggle-button {
position: relative;
content: "";
display: block;
width: 40px;
height: 14px;
border-radius: 3px;
background-color: #CECECE;
float: left;
}
.toggle-button::after{
content: "";
display: block;
width: 20px;
height: 20px;
float: right;
margin-left: -20px;
border-radius: 100%;
margin-top: -3px;
}
.toggle-button-red::after {
background-color: red;
}
.toggle-button-blue::after {
background-color: blue;
}
<div class="toggle-button toggle-button-red"></div>
<div class="toggle-button toggle-button-blue"></div>
I am creating a header that, after scrolling, does a variety of things using CSS and Javascript. I must just be overlooking something that is preventing the underline on hover from changing from black to white after scrolling. It is supposed to always be the same color as the links.
Here's the link to see: http://www.exploreloudoncounty.com/
Any ideas? Thanks!
HTML:
<a class="nav__link" href="https://www.exploreloudoncounty.com/explore">Explore</a>
<a class="nav__link" href="https://www.exploreloudoncounty.com/join">Join</a>
<a class="nav__link" href="https://www.exploreloudoncounty.com/about">About</a>
<a class="nav__link" href="https://www.exploreloudoncounty.com/contact">Contact</a>
CSS:
.nav__link {
margin-right: 1em;
font-size: 1em;
color: #000;
text-decoration: none;
transition: 0.4s;
display: inline-block;
}
.nav__link::after {
content: '';
display: block;
width: 0;
height: 2px;
background-color: #000;
transition: width .3s;
}
.nav__link:hover::after {
width: 100%;
}
.nav__link.sticky a {
margin-right: 1em;
font-size: 1em;
color: #fff;
text-decoration: none;
transition: 0.4s;
display: inline-block;
}
.nav__link::after.sticky a {
content: '';
display: block;
width: 0;
height: 2px;
background: #fff;
background-color: #fff;
transition: width .3s;
}
.nav__link:hover::after.sticky a {
width: 100%;
}
JS:
if (scrollPosition > 100){
document.querySelector('.nav__link').classList.add('sticky');
}
else {
document.querySelector('.nav__link').classList.remove('sticky');
}
You should change your css to this:
.nav__link.sticky::after
This because the .sticky class is in the same element as .nav__link.
And if you want to use the a element in your styling you should put this at the front of the code, like this:
a.nav__link.sticky::after
This because the classes are located within this element so the element has to be in front.
What errors do you get if you open console (by pressing F12)?
Because if this is your complete JS, then you'll be getting scrollPosition is undefined.
The source you linked has this JS and you see they declare it at the beginning as:
let scrollPosition = Math.round(window.scrollY);
They also wrapped it in a lodash function called _.throttle, but you can acieve the same with setTimeout, it just makes sure the function gets called every now and then (here 300 milliseconds).
I would like to complement #Kjvhout answer.
That solution works only for the first link due to the wrong selector on the JS part.
In order to fix it, I would do the following:
Remove the JS altogether, if you inspect the dom, you can see that the header contains already a sticky class, so no need to add a new one to the anchors.
Rewrite the CSS to match this DOM structure, something like this should work:
.sticky .nav__link:after {
display: block;
width: 0;
height: 2px;
background: #fff;
background-color: rgb(255, 255, 255);
color: #fff;
background-color: #fff;
transition: width .3s;
}
This should solve the issue and would be a better solution as you can get rid of the unused JS part.
The reason why #Kjvhout answer was working only for the first is the JS part, your selector document.querySelector('.nav__link') is only selecting one HTMLElement, to get all the collection you should use document.querySelectorAll('.nav__link') and then iterate over this collection and apply the corresponding class.
But as I said earlier, my solution is simpler as you don't need to deal with JS.
I'm trying to create my own product tour handling (after trying some like intro.js).
Here is a JSFiddle that I've just created.
What I have is a div with CSS:
.highlight {
position: fixed;
top: 14px;
left: 16px;
width: 54px;
height: 40px;
z-index: 1000;
pointer-events: none;
}
.highlight__overlay {
width: 100%;
height: 100%;
position: absolute;
z-index: 12;
top: 0;
left: 0;
border-radius: 5px;
transition: all .5s ease;
border: 2000px solid rgba(0 ,0 ,0 ,0.85);
margin: -1000px;
box-sizing: content-box;
transform: translate3d(-1000px, -1000px, 0);
pointer-events: none;
}
As you can see, the button is highlighted, and clickable, but other two button can also be clicked.
How can I make only the element in the highlighted area clickable?
Also - are there any product tour/tutorial JS libraries that I should be aware of? Those, that will basically have the functionality that I need.
I have updated your jsfiddle Here
I added pointer-events: none to the button section of your css and gave button One a class of enabledButton.
Then I added pointer-events: auto to the .enabledButton section of your css
With a single line of jquery you can remove the enabledButton class from all buttons:
$("button").removeClass("enabledButton");
You then add the enabledButton class only to the button you highlight.
Now, the button with the class of enabledButton will be clickable while all others are not. This way you explicitly enable the button you want the user to click while all other buttons are disabled by default.
You can use css to do something like
. disabled{
pointer-events : none;
}
And add this class to the other non-highlighted buttons.
Another solution that requires some Javascript, is to add a default Html disabled attribute to your buttons, and remove it only for the highlighted button using innerHTML of something similar.
I am trying to do a very simple quiz like this one:
https://www.sitepoint.com/simple-javascript-quiz/
I tried to make it more responsive and added this line:
<meta name="viewport" content="width=device-width,height=device-height,initial-scale=1.0"/>
It worked fine but when I add a long text on the alternatives of each question, the button "Next Question" stay behind the text, only on mobile (iphone 6, safari).
I tried to add a z-index: 1000; and nothing changed:
button{
font-family: 'Work Sans', sans-serif;
font-size: 22px;
background-color: #279;
color: #fff;
border: 0px;
border-radius: 3px;
padding: 20px;
cursor: pointer;
margin-bottom: 20px;
z-index:1000;
}
So, there's a few things wrong here. As said above you need to remove the height from .quiz-container and remove the absolute positioning from .slide.
What I would suggest is that you add display: none; to slide then your active style to display:block - this will correctly display the button where it should be. With that said, you will lose the fade effect. You'd need to add this CSS to get it back. Hope this helps!
.quiz-container {
position: relative;
margin-top: 40px;
}
.slide {
width: 100%;
opacity: 0;
display: none;
}
.active-slide {
opacity: 1;
display: block;
}
You set position: absolute to your quizz questions, so they will ignore the space of every element you set in HTML.
A large z-index will only put an element above another, that's the why you see the quizz questions above the button.
The problem will be solved if you increment the height of quiz-container on mobile screen (try use #media screen).
https://www.w3schools.com/cssref/css3_pr_mediaquery.asp
I recomend you to find another way to put your questions at the top of page instead using position: absolute
The problem really is that your quiz-container div has a fixed height of 200px, and you can't make it fluid because your slides have position:absolute, which removes them from the flow and prevents the parent growing in height accordingly.
So you need to re-think how to go about this.
An interesting approach would be to use flexbox, controlling which slide to show with the order property.
.quiz-container {
margin-top: 40px;
overflow: hidden;
}
#quiz{
display: flex;
}
.slide {
opacity: 0;
transition: opacity 0.5s;
/*gives each slide 100% width and prevents it from growing or shrinking*/
flex: 0 0 100%;
}
.active-slide {
opacity: 1;
/*sets the order to -1, so it's positioned before all other flex-items*/
order: -1;
}
So I know there are plenty of feeds about these issues and I've been through most of them yet I can't make it work. I get really lost with .js.
So I'm using very simple pop up windows that provide more contents on a topic by cicking on the title of the topic. I'm using a simple css code:
.black_overlay {
display: none;
position: absolute;
top: 0%;
left: 0%;
width: 100%;
height: 100%;
background-color: black;
z-index: 1001;
-moz-opacity: 0.8;
opacity: .80;
filter: alpha(opacity=80);
}
.white_content {
display: none;
position: absolute;
left: 20%;
top:25%;
width: 70%;
height: auto;
padding: 10px;
border: 6px solid #ed7d86;
background-color: white;
text-align: center;
z-index: 1002;
overflow: auto;
}
And html:
<div class="flex-item">
<a href="javascript:void(0)" onclick="document.getElementById('TITLE').style.display='block';
document.getElementById('fade').style.display='block'">TITLE</a>
<div id="TITLE" class="white_content">Something else about TITLE.
<a href="javascript:void(0)" onclick="document.getElementById('TITLE').style.display='none';
document.getElementById('fade').style.display='none'">Close</a></div>
</div>
This code works great until I try it on elements that are lower on the page in which case the box obviously continue showing at the set top and left position, which means that I have to scroll back up to see it. If I get rid of top and left conditions, I just end up with the box showing up randomly at some corner of the page.
I also want people to be able to leave the box just by clicking on the black_overlay area. Can anyone recommend a fix that would work with my code?
Ah well, not much success with my question. Wanted to let you know that I changed the position of the .white_content to fixed and it solved my problem for positioning. I'm still working on closing the window by clicking outside the box without changing all my code.