As the title say "Divide elements width depending on amount of elements"
I want to have an progress-like bar where I can add elements and depending on the amount elements I have the progress bar would split.
This is fixed values now (33%, 33% and 34%) and I want them to change depending of how many elements I use.
Like if I have 4 elements in my list I want it to automatically divide equally with 4. Is there any easy way to do it? Maybe using only CSS? I don't mind javascript, but Im just saying that it could be something I've missed :)
Edit:
I created 3 div's and gave them all different classes.
<section class="progress-part-list">
<div class="progress-part-left">
</div>
<div class="progress-part-right">
</div>
<div class="progress-part-mid">
</div>
</section>
In my CSS with my fixed values it is:
.progress-part-mid
{
height: 100%;
width: 34%;
background-color: #52ff00;
opacity: 0.9;
display: block;
float:left;
}
.progress-part-left
{
height: 100%;
width: 33%;
background-color: red;
opacity: 0.9;
display: block;
border-top-left-radius: 50px;
border-bottom-left-radius: 50px;
float:left
}
.progress-part-right
{
height: 100%;
width: 33%;
background-color: yellow;
opacity: 0.9;
display: block;
border-top-right-radius: 50px;
border-bottom-right-radius: 50px;
float:right;
}
Are you looking for something like this?
http://jsfiddle.net/FK7N5/
You want to select all the elements, and use that to calculate the percentage.
It doesn't matter how many elements you include in your container. Just make sure they all have a common class like "progress". Remember, you can have more than one class on an element, so you can have <div class="progress progress-first"> or <div class="progress progress-middle">.
The jQuery to make it work:
// Get all parts of the progress bar.
var bars = $('.bar');
// With each one, calculate the percentage and apply the width.
bars.each(function()
{
$(this).css('width', (100 / bars.length) + '%');
});
As a person who uses javascript more than I should, the first thing that came to mind is to run some JavaScript on load, and then it can go though the 'child' property of the surrounding element (the one with class progress-part-list), then divide 100 by that, then set the styles to that.
Here's some code that would do this:
<script type="text/javascript">
var divd=100/(document.getElementsByClassName('progress-part-list')[0].children.length);
[].forEach.call(document.getElementsByClassName('progress-part-list')[0].children,function(curChild){
curChild.style.width=divd+'%';
});
</script>
Put that just after the closing tag of the <section>
That's very crude, though, you might want to fix it to make it more elegant (like modifying class styles instead of inline styles, going through all instead of just the first progress-part-list, etc
It's also untested
Try giving each of the inside-elements a margin-right of -4px and use the following JS/jQuery:
$(document).ready(function(){
$('div div').width($('div:first-child').width() / 3);
});
Here's a fiddle: http://jsfiddle.net/JthgV/
Is that what you're looking for?
P.S. Forgive the inline style. I did it that way for the sake of saving time.
Related
I have a jQuery custom scrollbar, and I invoke it like this:
<script>
(function($){
$(window).on("load",function(){
$(".main_text,#C2,.png_container").mCustomScrollbar();
});
})(jQuery);
That works correctly for all of the page elements except .png_container, but unlike the other sections, that section is only used in a JavaScript variable that is used to substitute text in a placeholder ID, and I think that's where the problem is.
Here is how it's called from an "onclick" button event:
<div class="main_text">
<div id="C2">Main Text</div>
</div>
if (type == 101) {
var X = "<header>First Section</header><br>A classic example of good form/<br><br>More information<ul type=\"circle\"><li>Element Point 1<br></li><li>Element Point 1</li></ul><i><span class=\"span_01\">So much better</i></span><br><br><div class=\"png_container\"><img class=\"png_format\" src=\"images/Element 001.png\"></div>"}
document.querySelector("#C2").innerHTML = X;}
The png_container has a separate set of scroll bars, but they are not replaced by the custom scroll bars (the other page sections do get the custom scroll bars).
Here is the relevant css:
.png_container{
overflow: auto;
overflow-y: auto;
overflow-x: auto;
height: 400px;
width: 800px;
border: 2px solid;
border-color: green;
}
#C2{
color:#DBDBDB;
font-family: camphorW04-Thin,calibri,arial;
font-size: 14pt;
text-indent: 0px;
width: auto;
margin: auto;
margin-left: 20px;
margin-right: 250px;
}
So my question is: how can I replace the scroll bars on a section that is embedded in a JavaScript variable, as shown above?
My research has found some similar questions, but none that answer this specific question, so I hope somebody knows the answer. Thanks very much for any ideas.
You initialize the mCustomScrollbar plugin on load this way:
$(window).on("load",function(){
$(".main_text,#C2,.png_container").mCustomScrollbar();
});
The two first selectors have matching elements at this moment. But there is no existing element to match the last selector since .png_container is appended on click.
So you can safely remove .png_container from the load handler...
And initialise mCustomScrollbar on .png_container when it exists.
$(window).on("load",function(){
$(".main_text,#C2").mCustomScrollbar(); // Remove .png_container
});
$(".something").on("click",function(){
if (type == 101) {
var X = "<header>First Section</header><br>A classic example of good form/<br><br>More information<ul type=\"circle\"><li>Element Point 1<br></li><li>Element Point 1</li></ul><i><span class=\"span_01\">So much better</i></span><br><br><div class=\"png_container\"><img class=\"png_format\" src=\"images/Element 001.png\"></div>"}
document.querySelector("#C2").innerHTML = X;
$(".png_container").mCustomScrollbar(); // Add this.
}
I have three div's.
the first two are fixes width,but there width should not be set to permanent size because it could change. (base of the length of text that is there)
then next to those two I have a fluid div that will change his width dynamically when the user change his window size.
how can I set this kind of structure to work? even with the use of javascript
thanks.
I don't think you can have fixed width divs that resize dynamically unless you use javascript. Have you played around with min-width and max-width css attributes?
Have a look at this demo:
for a markup like this:
<div id="contentwrapper">
<div id="contentcolumn">
...
</div>
</div>
<div id="leftcolumn">
...
</div>
<div id="rightcolumn">
...
</div>
CSS
#contentwrapper {
float: right;
width: 100%;
margin-left: -430px;
}
#contentcolumn {
margin-left: 430px;
}
#leftcolumn {
float: left;
width: 230px;
background: #C8FC98;
}
#rightcolumn {
float: left;
width: 200px;
background: #FDE95E;
}
An example: http://jsfiddle.net/sw9422oy/
IF you don't want to set a fixed width then you should use a fluid-fluid-fluid approach like this one: http://www.dynamicdrive.com/style/layouts/item/css-liquid-layout-33-fluid-fluid-fluid/
Ok, so i want to have a series of divs which are the exact width and height of the user's browser window, regardless of the screen size. I can easily make the divs stretch horizontally with "width: 100%;" but i cant work out how to make the height stretch itself. I am guessing that i need to use some bit of javascript to judge the height, and then another piece to resize the seperate divs. Unfortunately I am a complete javascript n00b and after two hours of seemingly fruitless searching and coming up with about 100 "solutions" this was as far as id gotten (Im sure that at some point I have probably been closer to the answer):
var viewportHeight = "height:" + document.documentElement.clientHeight;
getElementById('section-1').setAttribute('style', viewportHeight);
<div class="section" id="section-1"></div>
<div class="section" id="section-2"></div>
<div class="section" id="section-3"></div>
edit:
ah i should be more clear, im attempting to have all three divs take up the entire screen, so you have to scroll down to see each one - almost like seperate slides. The idea is that each one takes up the entire screen so you cant see the next section until you scroll down, rather than having three divs which take up a third of the screen.
If you haven't already tried it, you'll want to look at parent:child inheritance of elements within the DOM by way of using CSS.
What I want to STRESS is that everyone giving you JS hacks to accomplish this is not only providing you with overkill (YOU did ask for a JavaScript solution, so they gave it to you!), but it's also a deviation from standards. HTML is for structure, CSS is for presentation, and JavaScript is for behavioral aspects... setting a div to the width of the viewport on load is a PRESENTATION aspect and should be done in CSS... not JavaScript. If you were trying to change the width based on events or user interaction, then yes JavaScript is your friend... but stick with just HTML and CSS for now.
The trick is that most elements have an undefined height - and height is later defined by the content that the element holds.
If you want to 'trick' an element into having a height other than what it wants to default to, you'll have to explicitly define it. Since you want to inherit your height from the viewport, you'll have to define the height at the top and bring it down...
You might be in luck and can avoid JavaScript altogether (unnecessary). Just use CSS.
Try something like:
html, body {
height: 100%;
width: 100%;
}
Now, when you try to set your div's later on, specify width: 100% and the height gets inherited from the html --> body --> div.
Try that and see if that solves your problem - if not, point us to a website, a pastebin, or a SOMETHING with code in it that we can just show you how to do it (whereas what you posted for code was an attempt in JavaScript which is only 1 part of the code - post the full thing either to a server or temp site like pastebin).
Here is some sample code I wrote (tested in Chromium):
The HTML:
<html>
<head>
<title>Test Divs at 100%</title>
<link rel="stylesheet" type="text/css" href="divtest.css"
</head>
<body>
<div class="test1">aef</div>
<div class="test2">aef</div>
<div class="test3">aef</div>
</body>
</html>
The CSS:
html, body {
width: 100%;
height: 100%;
background-color: #793434;
padding: 0;
margin: 0;
}
div {
height: 100%;
width: 100%;
}
.test1 {
background-color: #E3C42E;
}
.test2 {
background-color: #B42626;
}
.test3 {
background-color: #19D443
}
try this
div#welcome {
height: 100vh;
background: black;
color: white;
}
div#projects {
height: 100vh;
background: yellow;
}
<div id="welcome">
your content on screen 1
</div>
<div id="projects">
your content on screen 2
</div>
it should work for you, but little support in IE
A bit of jQuery should do it:
$(document).ready(function() {
var window_height = $(window).height();
$('#section-1").height(window_height);
});
And if you want to keep 100% height on window resize:
$(document).ready(function() {
function viewport_height() {
var window_height = $(window).height();
$('#section-1").height(window_height);
}
viewport_height();
$(window).resize(function() {
viewport_height();
});
});
try this
window.onload = init;
function init()
{
var viewportHeight = "height:" + document.documentElement.clientHeight+"px;";
document.getElementById('section-1').setAttribute('style', viewportHeight);
}
Here is a script free solution, just CSS. This assumes that the divs are directly in the body element or a parent with position absolute and the parent has no padding.
#section-1 {
position: absolute;
height: 100%;
width: 100%;
background: #ff0000;
}
#section-2 {
position: absolute;
width: 100%;
top: 100%;
height: 100%;
background: #00ff00;
}
#section-3 {
position: absolute;
width: 100%;
top: 200%;
height: 100%;
background: #0000ff;
}
See fiddle: http://jsfiddle.net/QtvU5/1/
I am trying to create a carousel, where clicking on any element will slide it leftwards, simultaneously sliding the right element into viewport. For that, I need to have the divs stacked side by side. I am trying it out as a float based layout (see Fiddle ).
Problem is that here clicking the red colored div slides it leftward alright, but not the green element leftwards. This is probably due to the fact that they are actually lying below another, as visible when the overflow: hidden is removed from #cont's style. How elese to stack them side by side so that sliding one leftward automatically slides the next one leftwards as well? (Creating the to-be-next element on the fly while clicking and animating it into viewport is a no-no, the element should be present in the DOM!)
I'd suggest you use a plugin, as there is more to this than you may realize. There are many plugins out there for this, here's a list to get you started: http://www.tripwiremagazine.com/2012/12/jquery-carousel.html
I modified your Javascript, HTML, and CSS to get you pointed in the right direction:
http://jsfiddle.net/nf5Dh/2/
You need a container contContent, positioned absolutely, and that container gets moved within the container div. You just float the elements in contContent to get them next to each other.
HTML:
<div id='cont'>
<div id="contContent">
<div id='i1'></div>
<div id='i2'></div>
<div id='i3'></div>
</div>
</div>
CSS:
#cont {
width: 50px;
padding-top: 10px;
background: blue;
height: 50px;
overflow: hidden;
position: relative;
}
#contContent {
height: 50px;
width: 150px;
position: absolute;
top: 0;
left: 0;
}
#contContent > div {
float: left;
display: inline-block;
height: 50px;
width: 50px;
}
#i1 { background: red; }
#i2 { background: green; }
#i3 { background: yellow; }
And the JS:
$("#contContent > div").click(function(){
$("#contContent").animate({left: "-=50px"},1000);
});
You'd probably be better off using an ul instead of all divs, this is at least more semantically correct, though not technically necessary.
<div id="carousel">
<ul id="carouselContent">
<li id="slide1"></li>
<li id="slide2"></li>
<li id="slide3"></li>
</ul>
</div>
This:
#cont {
white-space:nowrap;
overflow: hidden;
}
.pane { // or whatever the slide divs are called. get rid of the float.
float: none;
display: inline-block;
*zoom:1;
*display:inline;
}
You can use that carousel where you can generate javascript for the carousel http://caroufredsel.dev7studios.com/configuration-robot.php
I've used http://sorgalla.com/jcarousel/ for things like this in the past, that's based on postion: relative and left/right offsets. Probably easier than messing with floats.
You can try using a list item instead, and display them inline.
jQuery(".my_container").hover(function(){
//do code
}, function(){
//do code
});
.my_container { width: 100px; height: 100px; margin: 50px; }
The code above doesn't react to mouse over of margin (margin isn't a part of element?) - how can I change that?
You could use a 50px transparent border instead - the margin isn't really supposed to be mouseable...
Include a pseudo element, e.g.
.my_container:before {
content:'';
position:absolute;
top:-50px;
bottom:-50px;
left:-50px;
right:-50px;
}
This adds an extra 50px to the existing element's clickable area.
If you only want to add this on touch screen devices, you could do this:
.touchevents .my_container:before {
...
}
This requires something like Modernizer to insert the appropriate feature-based CSS class.
Update
As per #Jaladh's comments, you may also need to apply position:relative to the container element, since position:absolute above will be relative to the first ancestor with a position attribute:
.my_container {
position:relative;
}
Perhaps use a 2nd wrapper element with padding on the outer element and existing background and padding styles on the inner element:
<div class="my_container">
<div class="my_container_inner">
<!-- etc. -->
</div>
</div>
jQuery(".my_container").hover(function(){
//do code
}, function(){
//do code
});
.my_container { padding: 50px; }
.my_container_inner { width: 100px; height: 100px; /* etc. */ }
Building upon #Dunc's solution, you can alternatively use pseudo element to mimic your container and let actual container behave like margins. This will look like:
.my_container {
width: calc(100px + (2 * 50px));
height: calc(100px + (2* 50px));
position: relative;
}
.my_container::before {
content: '';
position: absolute;
top: 50px;
bottom: 50px;
left: 50px;
right: 50px;
}
Also make sure to move all other properties (like background color, border, etc.) you had in my_container to my_container::before because before is acting like our container here.
This is essentially helpful if your containers are grid items and you want gaps in-between them to be hoverable, because otherwise using psuedo element to add margins won't work appropriately in that case.
Change the margin to padding and it'll be hoverable.