How to know when ul too small for li - javascript

I am trying to make a responsive template like bootstrap, and i am trying to find a way to know if the ul is getting too small for the li elements.
I have a ul like this:
<ul>
<li>Element one</li>
<li>Element two</li>
<li>Element three</li>
<li>Element four</li>
</ul>
As you can see in the picture below, the ul(red line) is taking the whole page width:
And i want to do something if the ul's width equals that of the li elements.
Sorry, if this post is not the most easy to understand one.

You can pre-calculate the minimal width (the width that the li elements require in order not to break), and simply set the min-width to the ul:
ul {
min-width: 800px;
}
If you want to do something more when it reaches that size, you can use JavaScript to set a window resize listener in which you'd check the width of your ul element, and take appropriate measures based on its width.
See this simple example:
var ul = document.getElementById('d');
var lis = ul.getElementsByTagName('li')
var requiredWidth = 0;
var padding = 100;
for(var i = 0; i < lis.length; i++){
requiredWidth += lis[i].offsetWidth;
}
// make the ul red if it's not as wide as the width of lis plus the padding
function handleSize() {
if (ul.offsetWidth < requiredWidth + padding) {
ul.style.background = 'red';
} else {
ul.style.background = "";
}
};
window.onresize = handleSize;
handleSize();
#d {background: #eee}
#d li {
border: 1px solid;
display: inline-block;
min-width: 200px;
height: 50px;
background: green
}
<ul id="d">
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
<p>Go "Full Page" and then try shrinking the window size to below ~908 pixels</p>

ul is a block element that takes full width if no style is given. But if you want to limit the ul width's to it's li elements, you can simply make the ul element an inline element using display property.
<ul class="navigation">
<li>Element one</li>
<li>Element two</li>
<li>Element three</li>
<li>Element four</li>
</ul>
// Style
.navigation{
display: inline;
}

Related

if 'this case' and 'that case' do 'something' else do 'other something'

I'm trying to create an onClick function which only works below resolution of 768px. The function works on other resolutions such as 992px and above, but for some reason the function still works on resolution 768px itself.
following is my code:
$(document).on('click','.active-tab', function(e){
if ($(window).width() < 768) {
if($(this).hasClass('active')) {
$(this).removeClass("active");
$(this).siblings().slideUp("fast");
} else {
$(this).addClass('active');
$(this).parent().find('li').slideDown("fast");
}
}
e.preventDefault();
});
.active-tabs {
ul {
display: flex;
flex-wrap: wrap;
flex-direction: column;
list-style: none;
li {
display: none;
}
li:first-child {
display: block;
}
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div class="tabs">
<ul>
<li class="active-tab">ALL</li>
<li>TAB ONE</li>
<li>TAB TWO</li>
<li>TAB THREE</li>
<li>TAB FOUR</li>
</ul>
</div>
I'm trying to achieve something like this:
for when resolution is above 768
for when resolution is below 768
the onClick function whenever below 768
Is it the syntax where I am mistaken? or perhaps I'm forgetting something?
Appreciate the help guys, thanks.
Your main problem in your post seems to unfounded, but I did notice that there were some logic errors that would cause the first click not to work properly. If you need a reference to prove your check is working, click here (becuase you can't resize a SO snippet).
A different way of achieving a similar effect
I'd first recommend fixing your anchor tag. You could add javascript:void(0) into it or simply put #.
<li class="active-tab">ALL</li>
If you are only using this code to toggle visibility
However, there is one way to further simplify your code. You can use toggle to get around one of your if structures:
$(document).on('click','.active-tab', function(e){
if ($(window).width() < 768) {
$(this).siblings().toggle("fast");
}
e.preventDefault();
});
If you need more options
Here's a version of your code that uses toggleClass.
if ($(this).hasClass('active')) {
$(this).siblings().slideUp("fast");
} else {
$(this).siblings().slideDown("fast");
}
$(this).toggleClass('active');
Please use this code
HTML
<div class="tabs">
<ul>
<li><a class="active-tab" href="">ALL</a></li>
<li>TAB ONE</li>
<li>TAB TWO</li>
<li>TAB THREE</li>
<li>TAB FOUR</li>
</ul>
</div>
css
.tabs li{
display:inline-block;
vertical-align:top;
}
.tabs li a.active-tab{
color:red;
}
#media screen and (max-width: 767px) {
.tabs li{
display:block;
}
.tabs li:not(:first-child){
display:none;
}
}
jQuery
$('.tabs').on('click','a', function(e){
if ($(window).width() < 768) {
$(this).parent('li').siblings().slideToggle("fast");
} else {
$('.tabs a').removeClass('active-tab');
$(this).addClass('active-tab');
}
e.preventDefault();
});
$(window).on('load resize', function () {
$('.tabs li').removeAttr('style');
});

Opening an accordion and collapsing an existing one

I have created an accordion it works fine, the only thing which I would like is to close an already open accordion if another accordion is clicked on. Currently, the accordion open and close separately but if another is open I want the current one to collapse
HTML CODE
<ul class="accordion">
<li>Home</li>
<li>
Products
<div class="slide">
<ul>
<li>Product 1</li>
</ul>
</div>
</li>
<li>
Сlients
<div class="slide">
<ul>
<li>Product 1</li>
<li>Product 2</li>
<li>Product 3</li>
</ul>
</div>
</li>
<li>
About
<div class="slide">
<ul>
<li>Product 1</li>
<li>Product 2</li>
<li>Product 3</li>
</ul>
</div>
</li>
<li>Contact</li>
</ul>
CSS CODE
.accordion,
.accordion li .slide ul{
margin:0;
padding:0;
list-style:none;
overflow:hidden;
}
.accordion li{
overflow:hidden;
}
.accordion li .slide{
overflow:hidden;
height:0;
}
.accordion li.open .slide{
height:70px;
}
.accordion li .slide ul{
padding:0 0 0 20px;
}
JQUERY CODE
$(document).ready(function(e) {
$('.head').on('click', function(){
//checking if the parent has a class open assigned to it
if($(this).closest('li').hasClass('open')){
///TO CLOSE THE SLIDE//
$(this).closest('li').find('.slide').animate({'height':0}, 500);
$(this).closest('li').removeClass('open');
}
else{
///TO OPEN THE SLIDE////
//for dynamic height we ind the ul inside the sliding div and target its height
var autoHeight = $(this).closest('li').find('.slide ul').height();
//finding the closest slide in the DOM Tree, so that only that slide will open not all of them
$(this).closest('li').find('.slide').animate({'height':autoHeight}, 500);
//finding the closest parent of the clicked item so that only that parent will have the class assigned to it
$(this).closest('li').addClass('open');
}
});
});
I have added comments in the jquery code to make it easy to understand
Try this : You can animate and set height of all slide to 0 except the clicked one. see below code
$(document).ready(function(e) {
$('.head').on('click', function(){
//variable to store clicked slide
var $slide;
var $parentLi = $(this).closest('li');
//checking if the parent has a class open assigned to it
if($parentLi.hasClass('open')){
///TO CLOSE THE SLIDE//
$slide = $parentLi.find('.slide');
$slide.animate({'height':0}, 500);
$parentLi.removeClass('open');
}
else{
///TO OPEN THE SLIDE////
//for dynamic height we ind the ul inside the sliding div and target its height
var autoHeight = $parentLi.find('.slide ul').height();
//finding the closest slide in the DOM Tree, so that only that slide will open not all of them
$slide = $parentLi.find('.slide');
$slide.animate({'height':autoHeight}, 500);
//finding the closest parent of the clicked item so that only that parent will have the class assigned to it
$parentLi.addClass('open');
}
//close all slides except the clicked one
$('.slide').not($slide).animate({'height':0}, 500);
$('.head').closest('li').not($parentLi).removeClass('open');
});
});
JSFiddle Demo
Before this comment:
///TO OPEN THE SLIDE////
Just add this code:
$("li.open .head").trigger("click");
Then the .open li will close.
Along with Guedes fix, you can even use jquery slideUp and slideDown to avoid getting height dynamically and remove some css code too to make code more simpler.
JS
$(document).ready(function(e) {
$('.head').on('click', function(){
//checking if the parent has a class open assigned to it
if($(this).closest('li').hasClass('open')){
///TO CLOSE THE SLIDE//
$(this).closest('li').find('.slide').slideUp();
$(this).closest('li').removeClass('open');
}
else{
$(this).closest('ul').find("li.open .head").trigger("click");
///TO OPEN THE SLIDE////
//finding the closest slide in the DOM Tree, so that only that slide will open not all of them
$(this).closest('li').find('.slide').slideDown();
//finding the closest parent of the clicked item so that only that parent will have the class assigned to it
$(this).closest('li').addClass('open');
}
});
});
CSS
.accordion,
.accordion li .slide ul{
margin:0;
padding:0;
list-style:none;
overflow:hidden;
}
.accordion li{
overflow:hidden;
}
.accordion li .slide{
display: none;
}
.accordion li .slide ul{
padding:0 0 0 20px;
}

Equal spaced, full width menu?

I have a menu with four options which I need to sit below an image like so:
----------------------------------------------------------------
| This is an image |
----------------------------------------------------------------
Menu 1 Menu 2 Menu 3 Menu4
These size is responsive, so I'm positioning the menu items dynamically. My problem is how to calculate the menu widths so that the spacing is equal as well as Menu1 and Menu4 meeting the edge of the image.
Will you ever have any more than 4 menu items at a given time? If not you can easily just wrap the links within an unorded and assign the <li> widths to 25% each. See the below example:
HTML
<ul>
<li>Menu 1</li>
<li>Menu 2</li>
<li>Menu 3</li>
<li>Menu 4</li>
</ul>
CSS
ul {
list-style: none;
margin: 0;
overflow: hidden;
}
li {
float: left;
width: 25%;
}
If you have a fixed number of items, you can work out the percentage each one needs to be (like #Chris has shown).
If the amount of menu items can vary, you can use jQuery to determine the widths:
var imgWidth = $(".img").width();
var itemWidth = imgWidth / $("ul.menu li").length;
$("ul.menu li").width(itemWidth);
Here I'm getting the image's width, then dividing the width by the number of li elements, then applying this value as the width for each li element.
See Demo: http://jsfiddle.net/rwvhG/
In terms of the alignment, this can be done with CSS:
ul li
{
float:left;
text-align:center;
}
ul li:first-child
{
text-align:left;
}
ul li:last-child
{
text-align:right;
}
See Demo: http://jsfiddle.net/rwvhG/1/
You can do it entirely in CSS
Check this demo: http://jsfiddle.net/Gv7fZ/
HTML:
<div class="outer">
<img src="<put-image-url-here>">
<div class="menu">
<div class="menuitem">Menu 1</div>
<div class="menuitem">Menu 2</div>
<div class="menuitem">Menu 3</div>
<div class="menuitem">Menu 4</div>
</div>
</div>
CSS:
.outer {
margin: auto;
display: table-cell;
}
.menuitem {
float: left;
text-align: center;
width: 33%;
}
.menuitem:first-child {
text-align: left;
width: 16%;
}
.menuitem:last-child {
float: right;
text-align: right;
width: 16%;
}
Although you can use css to set 25% width this will not work so well if the menu items text width is very different. If you want it to be really exact then try the following:
HTML
<ul class="menu">
<li>Menu 1</li>
<li>Menu 2</li>
<li>Menu 3</li>
<li>Menu 4</li>
</ul>​
JavaScript
$(document).ready( function( ) {
var widths = 0;
var items = $(".menu > li");
var menu_width = items.eq(0).parent().width();
// total width of all existing li
items.each( function( ) {
widths += $(this).width( );
});
var gap = parseInt( ( menu_width - widths ) / ( items.length - 1 ) );
// set widths of list items except for last one. Last li gets pushed to edge
items.slice( 0, -1 ).each( function( ) {
$(this).width( $(this).width() + gap );
});
});
​Fiddle here
However, if the width of your menu items is pretty much the same you will probably be better off using CSS.
If your layout is responsive then set your menu items to be 25% width each and then set the last child to be text-align:right so that it lines up with the right margin.
#Menu ul li {text-align:left;display:inline-block;width:25%}
#Menu ul li:last-child {text-align:right}

javascript css positioning

Hi all...
i have a problem with my fixed header.
when i zoom in or resize the browser, some menu in my header losts/hidden i don't know where..
so this is my code :
<div id="header">
<ul>
<li>Menu 1</li>
<li>Menu 2</li>
<li>Menu 3</li>
<li>Menu 4</li>
</ul>
</div>
css :
body{
min-height:1000px;
}
#header{
position: fixed;
margin:30px;
}
#header ul{
display:block;
}
#header ul li{
float:left;
list-style-type:none;
width:110px;
text-align:center;
line-height:30px;
padding-bottom:3px;
background: #ccc;
}
demo : http://jsfiddle.net/YgvND/1/
I need javascript program to controls css position. My purpose when at zoom in, zoom out or resize the browser so css header position will change into "ABSOLUTE".
sorry on my language. x)
Anyone can help me....
thx..
i recommend you to use jquery. a good approach to check for resulution changes is described in here
I'm not totally sure I'm understanding your question, but I'll give it a go. It seems to me like you want to position the #header div as absolute when the page is resized. So, use jQuery to look for window resize.
This might be overkill in your situation. This will bind whatever css changes to the #header div as soon as the page is done being resized.
$(window).resize(function() {
if (this.resizeTO) clearTimeout(this.resizeTO);
this.resizeTO = setTimeout(function() {
$(this).trigger('resizeEnd');
}, 500);
});
$(window).bind('resizeEnd', function() {
var header = $("#header");
header.css({
position: "absolute",
top: "0px",
left: "0px"
});
});
Here's a demo.

CSS single select list example

I am looking for a click based single select list. Instead of the normal drop down list, I want an overlay menu (similar to how we see on facebook when we change privacy settings, the single select list that appears). Is that CSS based or any code examples to creating a similar list? All the lists i found of the net are hover lists not same as we see on f/b.
Thanks.
Something like this:
It is just a menu that pops up where use can pick an option.
If you were using jQuery it would be something like this plug-in
http://plugins.jquery.com/project/selectbox
I can't find a non JS-solution (and for JS I'm using jQuery to assign focus to an arbitrary element that would keep the sub-menu open (on the plus side, I'm pretty darn sure that Facebook will be using JavaScript, of some sort, to achieve their implementation too).
However, I've put together a couple of examples, these are, much like Facebook, simply dropdown lists, with a JavaScript handler to assign focus to the clicked element (to keep the sub-menu open regardless of mouse position on the page, until the user clicks elsewhere).
With that in mind, I've used the standard css dropdown-style mark-up:
<ul>
<li>Symbol
<ul>
<li>option 1</li>
<li>option 2</li>
<li>option 3</li>
</ul>
</li>
<li>Symbol
<ul>
<li>option 1</li>
<li>option 2</li>
<li>option 3</li>
</ul>
</li>
<li>Symbol
<ul>
<li>option 1</li>
<li>option 2</li>
<li>option 3</li>
</ul>
</li>
</ul>
With the css:
ul {
list-style-type: none;
padding: 0;
margin: 0 auto;
}
ul li {
display: inline-block;
position: relative;
width: 100px;
border-bottom: 1px solid #ccc;
}
ul li ul {
display: none;
width: 100%;
position: absolute;
top: 1em;
left: 0;
}
ul li a:hover + ul,
ul li a:active + ul,
ul li a:focus + ul {
display: block;
}
ul li ul li {
border: 0 none transparent;
}
And the jQuery:
$(document).ready(
function() {
$('li a').click(
function(){
$(this).focus();
});
}
);
Demo at JS Bin
Notice that I've used a elements, since focus is more easily assigned to anchors than plain, in this case, li elements. However a second version, with the same end result is achieved with the following jQuery:
$(document).ready(
function() {
$('li').click(
function(){
$('li').not(this).removeAttr('tabindex');
$(this).attr('tabindex','-1').focus();
});
}
);
Demo at JS Bin.
Addenda
Stu Nicholls, of CSS Play seems to have achieved a pure-css solution for this (with a gallery), but I haven't worked my way through his CSS to see how he did it.

Categories

Resources