Count children + change CSS - javascript

I am trying to dynamically give child A tags an even width based on the number of tags contained in a list. (eg. if 4 A's they will all be 25% width, 3 tags they will be 33%).
I have tried counting the number of children inside the div and dividing 100 by the var number with no success
jQuery
var numChildren = $("div a").size()
$('a').css({ width : 100/numChildren });
CSS
a { width: /*DYNAMIC*/ (all even) }
div {width: 100%; }
HTML
<div>
<a></a>
<a></a>
<a></a>
<a></a>
</div>

You can do it CSS-only, without counting the number of elements:
HTML:
<div class="wrapper">
<a></a>
<a></a>
<a></a>
</div>
CSS:
.wrapper {
display: table;
width: 100%;
height: 50px;
margin: 10px 0;
}
.wrapper > a {
display: table-cell;
border: 1px solid #000;
}
Demo

With your current code, if there are four elements, you are setting this:
width: 25;
I think you want this:
$('a').css({ width : 100/numChildren + '%' });

Try changing the jquery to:
var numChildren = $("div a").length;
$('a').css({ 'width', 100/numChildren + '%' });

HTML
<div>
<a>Test Me</a>
<a>Test Me</a>
<a>Test Me</a>
<a>Test Me</a>
</div>
JAVASCRIPT
var numChildren = $("div a").length;
$('a').css({ width : 100/numChildren+'%' });
alert(100/numChildren);
CSS
div
{
width:300px;
}
a
{
position:relative;
float:left;
background-color:#EEE;
}
JSFIDDLE LINK

I don't think you need to set width in percentage. As you are ultimately going to use javascript to evenly distribute width
HTML:
<div>
<a>One</a>
<a>Two</a>
<a>Three</a>
<a>Four</a>
</div>
Javascript:
var parent = $("div");
var anchors = parent.find('a');
anchors.css({ width : parent.width() / anchors.length });
CSS:
div > a {
background: red;
display: inline-block;
}
Demo

You can use this code :
jsFiddle here
HTML
<div id="content">
<a></a>
<a></a>
<a></a>
<a></a>
</div>
CSS
#content{
width:100px;
height:20px;
background:#888;
}
a{
height:20px;
background:red;
display:block;
float:left;
}
jQuery
$(document).ready(function(){
var numberChild = $("#content a").length;
$("#content a").css("width",(100/numberChild)+"%");
});

Oriol's answer is the correct one, if you don't need to support IE7 and below.
If you need support for these browsers, you can calculate the relative width as others already explained.
But if you know that you will never have more than n children, you can also do:
// assuming that will never have more than 4 children
$('div:has(a)').addClass('one');
$('div:has(a+a)').addClass('two');
$('div:has(a+a+a)').addClass('three');
$('div:has(a+a+a+a)').addClass('four');
and the css
div a { width: 100%; }
div.two a { width: 50%; }
div.three a { width: 33.3%; }
div.four a { width: 25%; }
demo

Related

jQuery get the height of an element with display:none property

Is there an easy way to get the height of a parent div which has a hidden child div inside? If not, what could be the hard way to achieve such a result?
PS: I know that this topic might be repetitive, but the other topics I have found were all with negative scored best answers.
var getHeight = $(".parent").height();
console.log(getHeight);
.parent{
position:absolute;
top:0;
left:0;
}
.visibleChild{
position:relative;
height:20px;
background-color:red;
}
.hiddenChild{
display:none;
height:20px;
background-color:green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="parent">
<div class="visibleChild">
This div is visible.
</div>
<div class="hiddenChild">
This div is hidden.
</div>
</div>
You can certainly get the height of the parent when a child element is not displayed, but it sounds like you want to get the height of the parent when all of the children's heights are accounted. In this case, you can make the child(s) hidden but displayed, grab the height, and revert:
/* parentSelector: selector we wish to know its height
* childSelector: children to display when measuring parent
*/
function getHeight(parentSelector, childSelector) {
var parent = $(parentSelector);
var children = parent.children(childSelector);
var styleState = [];
//set state
children.each(function (i) {
let c = $(this);
styleState[i] = c.css(['display', 'visibility']);
c.css({ display: '', visibility: 'hidden' });
});
var height = parent.css('height');
//revert state
children.each(function (i) {
let { display, visibility } = styleState[i];
$(this).css({ display, visibility });
});
return height;
}
$('#test > div').hide();
console.log(getHeight('#test', 'div'));
#test { background: brown; padding: 1em }
#test > div { height: 50px; background: yellow; margin: 1em 0 }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="test">
<span>span</span>
<div>div</div>
<div>div</div>
</div>
I hope this helps!

Margin issue with jquery load()

I am loading html page inside a div with jquery. It does work fine.
var loginBtn = $("#loginBtn");
var loginPage = $("#login");
var submitBtn = $("#submitBtn");
var submitPage = $("#submit");
var checkBtn = $("#checkBtn");
var checkPage = $("#check");
loginPage.load( "login.html" );
submitPage.load( "submitPoints.html" );
checkPage.load( "checkPoints.html" );
body {
margin: 0 !important;
padding: 0 !important;
background-color: white;
}
#mainFrame {
width: 100%;
height: 300px;
background-color:cadetblue;
padding-top: 0;
margin-top: 0px;
position: relative;
}
<div id="mainFrame">
<div id="login"></div>
<div id="check"></div>
<div id="submit"></div>
</div>
My issue is that if the loaded html has no content, the margin between the parent document body (white) and the top of the loaded html (green) is none (that's what I want, it's ok).
However as soon as I add content to the loaded html, a gap is generated at the top of the page :\
I thought it was all about setting some line-height prop in the css but it seems helpless.
Any ideas what I am doing wrong ?
What you are seeing is the top margin of the first piece of content overflowing its container (also known more commonly as margin collapsing):
body {
background:yellow;
}
#container {
background:green;
height:300px;
}
<div id="container">
<h1>I have a top margin of 1em by default that is overflowing into the body.</h1>
</div>
If you give your container element a padding of that same amount, the margin space of the body won't be used and the element will be pushed down in the green area.
body {
background:yellow;
}
#container {
background:green;
height:300px;
padding:1em;
}
<div id="container">
<h1>I have a top margin of 1em by default that is now contained within my parent.</h1>
</div>
Or, you could set the top margin of the first piece of content to zero:
body {
background:yellow;
}
#container {
background:green;
height:300px;
}
#container > h1:first-child { margin-top:0; }
<div id="container">
<h1>My top margin has been set to zero.</h1>
</div>
Finally, you could set the overflow of the content area to auto but (although this seems to be the popular answer), I don't prefer this approach as you run the risk of unintended fitting of the content as the content changes and/or the container size changes. You give up a bit of sizing control:
body {
background:yellow;
}
#container {
background:green;
height:300px;
overflow:auto;
}
<div id="container">
<h1>The content area has had its overflow set to auto.</h1>
</div>
When you load new content it gets rendered in the document and those new elements might have properties. In this case, most probably the Login has a margin value. Another option is that it has a class or some selector that is being picked up by a CSS file which appends the margin to it.
Easiet way would be to right-click on the Login element, choose inspect, and analyze the style of the element with web-dev / style.
If you want to keep the margin on the inner content, you should set an overflow. Look what happens when we remove the overflow: auto line from .content > div (try clicking the box after running the code sample below).
This is because of margin collapsing. The margin on the inner content is combined with the margin on the outer element and applied on the outer element, i.e. two margins of the two elements are collapsed into a single margin.
document.querySelector('.content').addEventListener('click', (e) => {
e.target.classList.toggle('overflow');
});
html,
body {
margin: 0;
padding: 0;
}
.outer {
width: 200px;
background: red;
}
.content > div {
width: 100%;
height: 300px;
background: cadetblue;
cursor: pointer;
}
.content > div.overflow {
overflow: auto;
}
.test {
margin: 10px;
display: block;
}
<div class="outer">
<div class="content">
<div><span class="test">Test</span></div>
</div>
</div>

JQuery Offset issue when div position is fixed

I have a website which has a page layout and style something like mentioned in this JsFiddle
Now Using JQuery when I click on the button, content is being displayed properly as shown below:
But when I first scroll the page and then click the button, content is not displaying properly as shown:
Can you please guide me to handle this situation ?
I have used below jQuery for this. But it seems offset or position is not working
$('#btn').click(function(){
var t = $(this).offset();
console.log(t);
$('.control-container').css('top', t.top + 20 + 'px');
$('.control-container').css('display', 'block');
});
$(document).on('scroll', function(){
$('.control-container').css('display', 'none');
});
You don't need to use offset to achieve that... And if you need to keep CSS with position:fixed, you need to switch it in javascript to static.
The thing you are looking for is simply display:table ...
$('#btn').click(function(){
$('.control-container').css({'display': 'table','position': 'static'});
});
$(document).on('scroll', function(){
$('.control-container').css({'display': 'none','position': 'fixed'});
});
Check out this JSFiddle
But if you really need a solution with position:fixed based on button position, you should try this way:
$('#btn').click(function(){
var button_fixed_position = $('#btn').get(0).getBoundingClientRect();
$('.control-container').css({'display': 'block','left' : button_fixed_position.left, 'top' : button_fixed_position.bottom});
});
$(document).on('scroll', function(){
$('.control-container').css({'display': 'none'});
});
Check out second JSFiddle
There is no need to specifically mention position property here.
Also remove the closing a tag and replace it with </button>
Currently container is occupying full width ,but that can also be set
$('#btn').click(function() {
var t = $(this).offset();
console.log(t);
$('.control-container').css('top', t.top + 30 + 'px');
$('.control-container').css('display', 'block');
});
$(document).on('scroll', function() {
$('.control-container').css('display', 'none');
});
.header {
background-color: maroon;
color: #fafafa;
height: 60px;
position: fixed;
width: 100%;
text-align: center;
line-height: 19px;
font-size: 25px;
z-index: 2;
padding: 0px;
margin: 0px;
top: 0;
}
.content {
background-color: #fff;
border: 1px solid #999;
padding: 5px;
height: 100%;
width: 100%;
position: absolute;
z-index: 1;
top: 60px;
}
.control-container {
width: auto;
background-color: red;
#position: fixed;
color: #fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="header">
Header
</div>
<div style="clear:both">
</div>
<div class="content">
<br/>
<br/>
<br/>
<br/>
<br/>
<button id="btn">Click Me</button>
<div class="control-container" style="display:none;">
Keep me exactly underneath 'Click Me' when Page is scrolled.
</div>
</div>
</div>
CSS position fixed property positions an element referencing view's/body's dimension.
If you have access of modifying CSS, then just remove the position: fixed; property from .control-container.
If you don't have access, then using script add position: static !important property to .control-container.
$('.control-container').css('cssText', 'position: static !important');
Modified JSFiddle

Generate div columns using jquery

following code on jsfiddle:
<div id="container">
<div class="b">test1</div>
<div class="b">test2</div>
<div class="b">test3</div>
<div class="b">test4</div>
<div class="b">test5</div>
<div class="b">test6</div>
</div>
CSS
.b {
display:inline-block;
position: relative;
margin: 2px;
float:left;
width: calc(16.7% - 10px);
height:400px;
background-color: white;
border: 1px solid black;
}
http://jsfiddle.net/329vcLLc/ does work, it shows 5 columns the way I would like them to be formatted.
I must loop over an array to generate the divs according to the number of elements of the div. I thought I could use the append() function, what do you think? and how can I set the width property for each div (cause it depends on the number of columns)
any ideas?
I don't quite understand what the number of the divs depends on, but if you need to generate some known number of divs you may do this:
var n=8;
var $cont=$('#container');
for(var i=1; i<=n; i++)
{
var d=$('<div>').addClass('b').html('test '+(i)).css('width', 'calc('+(100/n)+'% - 10px)');
$cont.append(d);
}
.b {
display:inline-block;
position: relative;
margin: 2px;
float:left;
height:400px;
background-color: white;
border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
</div>
According to your provided css you can do something like this:
var divs = ['a','b','c','d','e', 'f', 'g'];
var con_width = parseInt($('#container').width()); //get the width of the container
var width = (con_width / divs.length) - 10; //divide trough the number of divs,
//subtract 10 to make them fit
$.each(divs, function(index, value){
var div = $('<div />').addClass('b').text(value).css('width', width + 'px'); //generate new div
$('#container').append(div); //append it to the container
});
Demo
Reference
.each()
.width()
.css()
.addClass()
.text()

html page max-width by knowing the size of inside divs

This is my HTML code
<div class="container">
<div class="menu-vertical">menu-vertical</div>
<div class="mainContent">mainContent</div>
</div>​
This is my CSS
.container {
border: 3px solid #666;
overflow: hidden
}
.menu-vertical {
width: 230px;
float: left;
padding: 10px;
border: 2px solid #f0f
}
.mainContent {
overflow: hidden;
padding: 30px;
border: 2px solid #00f
}​
Now i want to make few div inside mainContent of fixed size lets say 150px however if the mainContent width became, lets say 650px then i'll be having 4 div in a row then again 4 in a row. So 4 div means it will be of 600px, hence i'll be having an extra 50px of space.
Now finally what exactly i want to do is to detect this empty space and making the mainContent max-width to 600px`. Any trick which can do this. Javascript or something.
Here is the solution using jquery:
$(function(){
var outerdiv = $('.mainContent');
var innerdivs = $('.mainContent > div');
var sum =0;
innerdivs.each(function(index){
sum += $(this).width(); //calculate and add the widths of every div
});
//outerdiv.width(sum); //set new width for .maincontent
outerdiv.css("max-width", sum); //you can also set max-width like this.
});
You can check out the jsfiddle for this here: http://jsfiddle.net/jqYK6/
Regards,
Saurabh
https://stackoverflow.com/a/10011466/1182021
Here is the link for the answer... after waiting for long i come up to this.

Categories