This works correctly for hover, but I am after two other things:
1) a more scalable, generalized solution: every time I add a link and paired paragraph I don't want to have to also include specific CSS for each addition. It seems like I should be able to create the same behavior for each paired link and paragraph generally and apply it to all of the pairs. What I have seems very inefficient.
2) I'd like to also create the same behavior as the hover, but for a click and make it scalable and generalized (as #1 above). The desired behavior is click on link -> paired paragraph appears, click on link again -> paired paragraph disappears again (or something very similar).
Note: I want both click and hover because hover will work for a desktop, but not mobiles. If someone is on a smart phone they can use the click. I'd like solutions to be responsive, to avoid jQuery, and to use CSS only if possible.
Here is what I have now (using only two pairs links and paragraphs, for simplicity):
Markup:
<a id="a-1">link1</a>
<p id="p-1">para1</p>
<a id="a-2">link2</a>
<p id="p-2">para2</p>
CSS:
#a-1,#a-2{
display: block;
}
#p-1,#p-2{
display: none;
}
#a-1:hover ~ #p-1 ,#a-2:hover ~ #p-2{
display: block;
}
Here is a demo: http://jsfiddle.net/CzpZ6/
You can use :target attribute, in conjunction with specific IDs (see demo)
HTML
<a class="focus" href="#p1">
Click me or hover me
</a>
<p id="p1">I'm hidden</p>
<a class="focus" href="#p2">
Click me or hover me
</a>
<p id="p2">I'm another hidden paragraph</p>
CSS
.focus {
display: block;
}
.focus:focus, .focus:hover {
background-color: pink;
}
.focus + p {
display: none;
}
.focus:hover + p, p:target {
display: block;
}
Here is your generalized solution:
http://jsfiddle.net/8vA32/
a{
display: block;
}
p{
display: none;
}
a:hover + p {
display: block;
}
If you use plus that will select all the p values until it finds another element. So in this case + can work.
For mobile part you can use this:
/* #### Desktops #### */
#media screen and (min-width: 1024px){
/* some CSS here */
a{
display: block;
}
p{
display: none;
}
a:hover + p {
display: block;
}
}
#media handheld, only screen and (max-width: 480px), only screen and (max-device-width: 480px)
{
a{
display: block;
}
p{
display: none;
}
a:active + p {
display: block;
}
}
On desktop part it will trigger hover, on mobile part it will trigger click.
Example:
http://jsfiddle.net/8vA32/
I believe a jQuery solution is your ONLY solution. For both hover and touch events to work you will need to turn off click and bind touch. here is a piece of script I use in a Nav menu for tablet size when users may be using either touch or mouse. Perhaps if you know js you can modify this script to fit your need:
function medMenu() {
//reset the menu in case it's being resized from a small screen
// unbind click events
jQuery('.menuToggle a').off('click');
jQuery('.topMenu h3').off('click');
// remove any expanded menus
jQuery('.expand').removeClass('expand');
// remove the span tags inside the menu
jQuery('.topMenu h3').find('span.indicator').remove();
// remove the "menu" element
jQuery('.menuToggle').remove();
//check to see if the device supports touch
//we'll use touch events instead of click as it will allow us
//to support both a CSS-driven hover and touch enabled
//menu for this screen range
if ('ontouchstart' in document.documentElement)
{
//find all 'hover' class and strip them
jQuery('.topMenu').find('li.hover').removeClass('hover');
//add touch events to submenu headings
jQuery(".topMenu h3").bind('touchstart', function(e){
//find the current submenu
var currentItem = $(this).siblings('.submenu');
//remove the expand class from other submenus to close any currently open submenus
jQuery('ul.submenu').not(currentItem).removeClass('expand');
//open the selected submenu
$(this).siblings('.submenu').toggleClass('expand');
});
//close submenus if users click outside the menu
jQuery('html').bind('touchstart', function(e) {
jQuery('.topMenu').find('ul.submenu').removeClass('expand');
});
//stop clicks on the menu from bubbling up
jQuery('#mainNav').bind('touchstart', function(e){
e.stopPropagation();
});
}
//indicate current window state
windowState = 'medium';
}
Change out the id tag for a generic class
JSfiddle Demo
HTML
<a class="a1">link1</a>
<p>para1</p>
<a class="a1">link1</a>
<p>para2</p>
CSS
.a1 {
display: block;
}
p {
display: none;
}
.a1:hover + p, /* the first p after an .a1 anchor */
.a1:focus + p {
display: block;
}
Related
I know the title is too general. I couldn't find a specific title.
Here is the sample https://jsfiddle.net/Exlord/1soagsL5/
HTML
<ul>
<li>item1</li>
<li>item1</li>
<li>item with submenu >
<ul>
<li>item1</li>
<li>item1</li>
</ul>
</li>
<li>item1</li>
<li id='clickable'>item1</li>
</ul>
JavaScript
var el = document.getElementById('clickable');
el.addEventListener('click', function(e) {
console.log(e.target);
}, false);
CSS
ul {
list-style: none;
margin: 0;
padding: 0;
width: 200px;
max-width: 100%;
}
li {
background: gray;
padding: 5px;
border: solid 1px black;
position: relative;
}
li:hover > ul {
display: block;
}
#media all and (min-width: 481px) {
ul ul {
display: none;
position: absolute;
left: 100%;
top: 0;
}
}
#media all and (max-width: 480px) {
ul ul {
display: none;
}
}
Try it, it's a very simple menu, hover the middle item item with submenu, a simple submenu will be shown with simple CSS :hover.
Click on the last item, it has a click event, it will fire correctly.
Now open this in Chrome's mobile device mod with touch simulation.
Click/touch the item with submenu, the submenu will open inside the parent element. This is the expected behavior.
Now click/touch the last element. The click event will not fire.
How can I fix this with CSS only hover?
UPDATE : As far as I can tell the problem is that on first touch the last hovered element (li with submenu) gets unhovered and the submenu ul gets hidden and the parent ul's height shrinks and the li element that was under the touched point moves up, so its not under the touched point anymore and it does not get clicked/touched !!!!
I think you figured out the cause on your own. The click target does seem to move away before event reaches the element.
The easiest solution I see is to use some supplementary Javascript to open and close the submenu on clicks. You use Javascript for the #clickable event anyway so a little more won't be detrimental, just as long as you keep the :hover for cases where Javascript is fails to load.
Original Answer
Touch devices do not have a hover state, due to the hardware
interface. Browser makers chose a compromise to allow for sites which
rely on it. Whenever a hover event/style is defined for an element the
first tap will trigger that effect instead of the click. A second tap
should, at least in most cases, trigger the original click event.
For your particular case you don't have a ul within the
li#clickable, but the :hover is still detected and the browser
behaves as it was designed. Excluding your #clickable from the hover
event will theoretically fix it (I am not able to test it myself at
this time).
li:not(#clickable):hover > ul {
display: block;
}
So, the word is International for example.
I would like to do something like this for mobile phones for example:
<span class="word-international">International</span>
and then style as follows for mobile phone:
.word-international{
content:"Int'l";
}
for obvious space reasons (and SEO reasons). This does not work, but I seem to remember there is some way to do this, I just cannot recall the specific HTML tag or attribute within the tag, something like <abbr> - thanks!
Css content property only works on :before, :after pseudo elements, it doesn't work on the direct elements. So you could do something like this
HTML
<span class="test">
<span>Hello</span>
</span>
CSS
#media only screen and (max-width: 767px) {
.test span {
display:none;
}
.test:after {
content: "Test";
}
}
If you are using a mobile first approach, then change the css accordingly, hope this helps
If you really need to physically change the content in the same element I can think of one way to do this. You have to create a pseudoelement for mobile devices
#media (max-width:720px) {
.word-international::before {
content:"Int'l";
font-size:12px;
}
.word-international {
font-size:0px; //hide text only. if you hide whole element the pseudoelement won't be visible as well.
}
}
But I'd suggest using some js to change the content of element or even better have two elements with classes mobile and desktop and use media queries to show/hide them
#media (max-width:720px) {
.word-international.mobile {
display: block;
}
.word-international.desktop {
display: none;
}
}
#media (min-width:721px) {
.word-international.desktop {
display: block;
}
.word-international.mobile {
display: none;
}
}
This is the way it's usually done.
I want to be able to turn a simple unordered list into a nice menu when on mobile:
<ul class="jumpToList list-inline">
<li>Buttons</li>
<li>Select</li>
<li>Input</li>
<li>Checkboxes & Radios</li>
<li>Switches</li>
</ul>
So when I'm on mobile the above gets turned into a simple menu with the 3 bars when then folds down the links.
Similar to how the Bootstrap navigation menu works, but so it doesn't conflict with this.
I ideally want to use the built in stuff with Bootstrap for this, good example of what i am after:
http://ux.mailchimp.com/patterns/forms
If you shrink the browser you will see that list turn into a menu on mobile.
Thanks
Some simple modifications to your HTML, media-queries and Javascript should allow you to replicate this behaviour.
I would suggest that you begin by creating the media-query to alter the applied styles based on device width.
CSS - Mobile first
.list-inline {
display: none;
visibility: hidden;
}
.list-inline-active {
display: block;
visibility: visible;
}
.list-inline li {
display: block;
}
#media (min-width: 600px) {
.list-toggle {
display: none;
}
.list-inline {
display: block;
visibility: visible;
}
.list-inline li {
display: inline-block;
}
}
HTML - Add toggle button/icon
<button class="list-toggle">Show list</button>
Javascript/jQuery
$('.list-toggle').click(function(){
$('.list-inline').toggleClass('list-inline-active');
});
This method simply uses a button to toggle a class on the unordered-list element. The toggled class contains styles to make the list visible on mobile.
I've created a simple JSFiddle example to show this in action.
It's worth noting that this behaviour is almost entirely replicable without the use of Javascript at all. It would involve the use of checkboxes and the ':checked' pseudo selector. However Bootstrap 3 does use Javascript.
I hope this helps.
My aim is to make the p tag with show class get displayed when the span (with Show Me text) is clicked. I had tried to do this using the :focus pseudo-selector but using this method makes the p tag get displayed only till somewhere else is clicked, where the p tag gets hidden again.
Is there any way to make the :focus selector display even after clicking away (or) is there a different/better way (without using JS) to display the p when the Show Me is clicked and make it stay that way even after clicking outside?
Fiddle Demo
HTML CODE
<span class="span1" tabindex="0">Show Me</span>
<p class="show" >This will show on click</p>
CSS CODE
body {
display: block;
}
.show {
display: none;
}
.span1:focus ~ .show {
display: block;
}
The :focus pseudo-class will not work because, as the naming indicates, it is applicable only when the focus is on the element and there is no way to make the focus 'stick' even after we click elsewhere.
An alternate way of achieving this would be to use the :target [1] pseudo-class/selector. This would make the p display whenever the link is clicked, since it is deemed as 'the target'.
body {
display: block;
}
.show {
display: none;
}
#content:target {
display: block;
}
<a class="span1" href='#content'>Show Me</a>
<p class="show" id='content'>This will show on click</p>
[1] - :target selector is not supported by IE <= 8.
I'm trying to make a sidebar that only appears when a triangle is clicked and I've gotten to the point where you click the triangle and it appears using:
sidebar {
display: none;
}
a:active + .sidebar {
display: block;
}
However as soon as you let go it disappears. How can I make it stay visible until you click the triangle for a second time? Below is the link to full code.
http://jsfiddle.net/Vqmaw/
You will have to use JS to toggle the visibility of the sidebar - a CSS solution is not possible.
$('a').click(function () {
$('.sidebar').toggle();
});
You will also have to set display: none for the .sidebar element. I have updated your fiddle - http://jsfiddle.net/teddyrised/Vqmaw/3783/
Your modified fiddle has a few issues - you are using MooTools instead of jQuery, and your class selector is improperly formatted.