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.
Related
I have a horizontal menu built using a <ul> element. I'm trying to get it to evenly spread out each <li> across the width of the menu. Based on several answers here on SO, I used the following CSS:
ul {
display: table;
width: 100%;
}
ul li {
display: table-cell;
}
However, no matter what I try, the <li> elements still end up with a calculated display of block, with this contradictory information from the debugger (tested in FF and Chrome):
I didn't know what is going on here, and (more importantly) how do I get my list items to display as table-cell?
In photo is showed that your style.css is really big (min.1835 lines) and because of that styles to ul could be overvritten somewhere.
To make your rule more important than existing rule, use !important keyword after rule like so:
ul {
display: table!important;
width: 100%!important;
}
ul li {
display: table-cell!important;
}
CSS has a trait called importance, it chooses which rules are the most specific and thus should override more loose rules. As you seem to use a CSS framework, your own rules don't override the framework's generic rules. Turns out that you have two options to increase the importance of your rules at main.css:
Add !important after your rules:
ul li {
display: table cell !important;
}
Make your selectors more specific:
#menu ul li.menu-list-item { ... }
Your question also looks very strange and you may be subject to a browser rendering bug, have you tried it out with other browsers?
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;
}
My dropdown menu made using bootstrap is hiding behind the slider that I made. I want it to show in front.
I have tried using:
z-index
overflow:visible
position:relative
according to the various solutions posted online under a similar problem. I have found no success with any of the solutions I tried.
I have a JSFiddle here https://jsfiddle.net/8wq0ptrw/
remove the overflow:hidden from your nav-bar class. I hope this will help you.
.nav-bar {
list-style-type: none;
margin: 0;
padding: 0;
}
You can see it by removing display: none; from .navbar and .collapse.
I believe bootstrap provides a hamburger menu icon that you need to implement where you click it to remove the display: none; on these elements and show the the dropdown menu.
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.
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;
}