What changes when appending a relative element? - javascript

I've noticed that when I append a relative element to another element something changes and the subsequent elements are always added to the right of the previous, so it seems that at some point during the append a left value is changed but I can't figure out which?
A small example would be adding 5 spans to a div and placing them all at left:10 and top:10
To have them on top of each other you'd have to take the amount of items added from the left value. i.e once you add 5 items the following item's left will be 10-5*10
Are there any other ways to find out what the left value of the appended item should be so it goes on top of the previous?
Here's some code examples and a jsfiddle link
Html
<div id="container"></div>
<span id="el" class="drag"></span>
Javascript
for(var i=0;i<5;i++)
{
var element=$('#el').clone();
$(element).html(i);
$(element).attr("id","el"+i);
$('#container').append(element);
$(element).css({
left: 10,
top: 10,
position: 'relative',
marginRight: 0
});
}
$('.drag').draggable();
Update:
I'm not so much looking for a "fix" as I have it working I'd just like to know if there's a value change in the element once a relative element is appended or removed from it

I'm not so much looking for a "fix" as I have it working I'd just like
to know if there's a value change in the element once a relative
element is appended or removed from it
The css from an element doesn't change if you add another element to it if that is what you are asking. The behaviour you see is caused by the browser fitting the elements like you asked it to. Since 'left: 10; top: 10;' is already occupied, it tries to fit it somewhere near there. That said, there is nothing stopping you from counting the amount of elements that a certain element contains. ($('#container').children().length), or the offset of an element on the page (the actual position; $('#el4').offset().left or $('#container .drag:last-child').offset().left). Because relative elements position themselves always relative to other elements, this is most likely not going to help you much.
To have them on top of each other you'd have to take the amount of
items added from the left value. i.e once you add 5 items the
following item's left will be 10-5*10
Are there any other ways to find out what the left value of the
appended item should be so it goes on top of the previous?
If you want the elements to actually stack, you probably need to alter the code so they are properly displayed next to each other, then use margin-left to move the left border into the element, so they are displayed over each other. .draggable() will calculate the position from there, and as long as you don't alter the DOM after you've made the elements draggable you should be fine.
Example jsfiddle: http://jsfiddle.net/LmW8T/2/
for(var i=0;i<80;i++)
{
var element=$('#el').clone();
$(element).html(i);
$(element).attr("id","el"+i);
//$element.addClass('element');
$('#container').append(element);
}
$('#el').remove();
$('.drag').draggable();
With CSS:
.drag {
width: 40px;
height: 40px;
border: 1px dotted blue;
background: #FEEFEF;
display: block;
float: left;
margin-left: -25px;
}
#container {
padding-left: 25px;
width: 200px;
}

This happens because when you use position:relative the element still occupies its space on the page, affecting the other elements. That's why each 10px left property you add, pushes the next element to the left also.
As already pointed out on the comments, using position:absolute solves the issue, as the "absolute" value makes the element float out from the page, and it doesn't occupies its space anymore, also it does not affect other elements.

Related

Change element css styling with js or jquery on the fly

I want to be able to change my navbar position on the fly adjusting remaining content accordingly.
So, I have a functiona website. There is a menu navbar on top by default. What I did is added an 'edit' button to that menu so that when you click it, you get a list of 4 checkboxes with the ability to choose if you want that menu positioned on top (default), left, right or bottom with the other content moving accordingly (e.g menu on the left, content goes slightly right, etc). So basically, I have something like this:
// css for menu positioning to the left
.navbar-left {
width: 25%;
height: auto;
}
.content-right {
position: relative;
left: 200px;
}
// css for menu positioning to the bottom
.navbar-bottom {
position: relative;
bottom: 0;
left: 0;
height: 200px;
}
.content-up {
position: relative;
bottom: 200px;
}
And in JS I do something like this
if($("#left"):checked){
$("#menu-bar").addClass("navbar-left");
$("#content").addClass("content-right");
} else if ($("#bottom"):checked){
$("#menu-bar").addClass("navbar-bottom");
$("#content").addClass("content-up");
}
Now, I have much more styling than this, but it is irrelevant to the issue at hand. The problem is when I choose 'left' it styles properly but when I change it to 'bottom' after that it still uses the styles from 'left' positioning and adds the new ones to it.
Right now I solved the issue by removing the previous classes with .removeClass() method, like that:
if($("#left"):checked){
$("#menu-bar").removeClass("navbar-bottom navbar-right").addClass("navbar-left");
$("#content").removeClass("content-up content-down").addClass("content-right");
} else if ($("#bottom"):checked){
$("#menu-bar").removeClass("navbar-right").addClass("navbar-bottom");
$("#content").removeClass("content-down").addClass("content-up");
}
Basically, right now I have about a hundred lines of just adding classes of the chosen positioning while removing all the classes of 3 other choices that I added each time.
So, finally the question: Is there any other way to strip all the classes that were used before (just set everything to initial values like when the page was loaded) instead of deleting all these classes by hand?
I haven't ever tried resetting the classes to their initial state, but you can certainly clear them all off of a single element in one line of code:
To replace all existing classes with another class, we can use .attr( "class", "newClass" ) instead.
source: https://api.jquery.com/removeclass/
You could probably combine that with the .toggleClass or another method.
If I had to sit down and do it right now, based on my understanding of your question I'd just hide the original elements and add new elements with the classes that you'd like, then to revert delete the new elements and restore the original one.

CSS position image relative to right hand side of div

There is a <div></div> in my Angular project, that's displaying a dialog when the user click an 'Edit' button to edit field in a table.
I have just added a 'close' button to the dialog, but am having some trouble positioning that button correctly...
The <div></div> is defined with:
<div class="provContactSelector" *ngIf="payer.showProvContactSelector">
...
<button class= "icon icon-close-selected" ...></button>
...
</div>
In the .scss file, I've added the block for this <div>, and added some styling to the icon:
.provContactSelector {
.icon {
appearance: none;
background-color: transparent;
position: relative;
border: none;
right: 50px;
}
}
I want the close button to be displayed just slightly in from the right hand side of the dialog, but as it stands, it's currently displayed just over half way across the width of the box, and so is displayed on top of the dialog title.
If I change the positioning to right: 5px;, recompile the CSS, and view the page in the browser again, I can see that the close icon has moved further to the right, but is now just right at the end of the dialog title, and there is still a lot more space to its right, before the edge of the dialog...
How can I anchor the close icon to the right hand side of the dialog, so that it's always displayed relative to where that is?
you defined the icon as position: relative. For what you descrived, I understood that you want to position the icon in absolute way, taking provContactSelector as the reference. In this case you should change the css to the following:
.provContactSelector {
position: relative;
.icon {
appearance: none;
background-color: transparent;
position: absolute;
border: none;
right: 50px;
top: 50px; // or whatever the value you need
}
}
Explanation:
position css instruction can be a bit tricky, and I have a lot of people having some confusion with how it works. So I will try to briefly explain what is happening:
position: static is the default value of a normal html block, and it positions itself depending of the other blocks that are around it. css like "top, left, right, bottom, z-index" won't work on them.
position: fixed an element defined as fixed will ignore all the blocks defined in the page and will position itself using the windows element (the whole document) as reference. you can position it using css like "top, left, right, bottom". You can define if other elements are on top of it or under it using "z-index".
position: absolute an element defined as absolute will ignore all the blocks defined in the page and will position itself using its nearest parent that IS NOT position: static as a reference. You can position it using css like "top, left, right, bottom". You can define if other elements are on top of it or under it using "z-index".
position: relative can be defined as an hybrid between absolute and static. The element will take in account the blocks that are near itself to find its position in the document. however, you can modify that position using "top, left, right, bottom", but that position will use as a reference the original place the element was located. This type of elements can also use "z-index".
Overall, position relative has properties from "absolute" and "static". I have yet to see a "position: relative" element in where using "top, bottom, left, right" is justified, because makes the element to be less predictable, and you can displace it using padding or margins instead.
Usually, position relative elements are defined not because you can position them with "top, left, right bottom" but because making them relative will let you position elements inside of them with "position: absolute" taking the relative element as reference.
Most of the problems I have found that confuse people is due the name they have: "absolute" looks like you will position the element taking in account only the windows, and "relative" sounds like you are using other element as base. However, the truth is that "absolute" is not absolute at all, it takes is position in relation of other element.
edit: as geeksamu mentions, the "icon" is a class, so it should have a dot before.
I think the problem with your code at
.provContactSelector {
icon {
icon is a class so it should be .icon not just icon
With the settings you use, the element will be moved 50px left of its original position, because you use position: relative; and right: 50px (i.e. right border 50px away from original right border). To achieve what you describe, you should use position: absolute;. But note that for the absolute position to relate to the parent element, the parent element needs to have position: relative;.

ui-sortable not working (for predefined DOM positions)

Please see this demo Click Here
Item 3 does not get sorted.How To make every element sort perfectly?
Note : Item 3 is float:right thats the need in project.
Acually in my project I have used DOM positions (eg:left:20px , right:10px) rather than float left or right.
If anyone can make this
Demo workable than it would be huge help.
What i want is all the elements should sort (specially item 3 which is not sorting).
What I tried is this .Which is not perfect.
Explanation :when user drags a element to left side of parent div and drops than the element sticks to left of div .. if dragged to right it sticks to right. thats the reason i am using DOM positions. Now I have to make it sortable too.
The sort works, it's the css that is causing you problems. Try this way:
https://jsfiddle.net/or6m2v4z/4/
What I changed:
#sortable li { margin: 0 3px 3px 3px; padding: 0.4em; padding-left: 1.5em; font-size: 1.4em; height: 18px; float:left}
#sortable li:last-child {float:right}
And I also removed the inline styles :)
EDIT
I just read the explanation you provided, if you want to drop elements left or right, maybe you should use a left and a right container and try with the droppable function instead of sortable.
drag drop and change parent of a div in dom
EDIT 2
I did a little workaround for you. Try this:
https://jsfiddle.net/or6m2v4z/5/
By having float: right on Item 3, you're explicitely telling the browser to position to the right hand side of everything else in the same block that is not styled with float:right.
If you have a look at the DOM in your browser's dev tools after having tried to move Item 3, you'll see that it has actually been repositioned.
Edit:
I guess this does what you need? https://jsfiddle.net/or6m2v4z/6/
Instead of having the float style on the items themselves, they've been wrapped inside two containers floating left and right respectively.
Using the sortable connectWith option, both containers can be linked so that their contents can be moved freely among them.
The containers need minimum dimensions so they don't disappear if empty (that's also the reason I added the gray background).

Keeping images in place after others are removed?

I am working on a memory matching game. Right now, when the user clicks on two identical images, they are removed. This part of the game works fine. When the images are removed, I want the other images to stay in place. However, they are shifting towards each other and not leaving space.
Demo: http://jsfiddle.net/kevinferri/bCP4G/
For example, click on the two flowers in the middle column. You will see that the the two outer columns will shift towards each other and fill that empty space. How can I change it so the images will stay in place after others are removed?
You probably don't want to be .remove()-ing elements if you want to the DOM to remember their original layout spacing and sizes. You want to just chuck those elements into hidden visibility so that they're hidden, but they maintain their size and position.
$(element).css('visibility', 'hidden');
That's visibility:hidden in CSS. Do take note of the difference between that and .show() / .hide() or even CSS display:none.
You'll want to give your tds some fixed sizes:
<style>
#playCards td { width: 200px; height: 200px; margin: 0; padding: 0 }
</style>

CSS Place one div directly over another

I have a div which has some stuff in it, and the user has the option of clicking an 'x' to say "This is not applicable to me", for example.
Rather than delete the div, I want to play a translucent div on top of it.
I started off with some complicated javascript to determine the size and location of my div in question, and create a new one on top of it. The script was giving a size and location which looked approximately right to my eye, but the overlap div was being put in the wrong spot.
Then I realised that there is (probably) a much simpler way to do this.
I put a div with class "blackout" inside the div I want to black out. The blackout css class has a visibility set to hidden, so javascript will set that to visible when needed.
The issue I'm having is that even with this method, I can't seem to get it to precisely fill the rectangle the parent div has.
I had
.blackout
{
position: absolute;
left: 0px;
right: 0px;
top: 0px;
bottom: 0px;
background-color: black;
opacity: 0.5;
filter: alpha(opacity = 50);
}
This filled up the whole screen rather than just the parent div.
What do I need to change to make it fill the parent div only?
This filled up the whole screen rather than just the parent div.
What do I need to change to make it fill the parent div only?
You need to add position: relative to the parent div.
That will set the parent div as the "containing block" for .blackout:
If the value of the position property is absolute, the containing
block is the nearest positioned ancestor—in other words, the nearest
ancestor whose position property has one of the values absolute,
fixed, or relative.
Read more here: http://reference.sitepoint.com/css/containingblock
Using "position:absolute" positions it in relation to the next "position:relative" div. If there isn't one set then it will use the body.
You need to make the parent div CSS contain "position:relative"
On the parent div's CSS:
overflow: hidden;
should work
Add position: relative to the parent div, overflow: hidden will only hide the outside of your parent's div
Change position: absolute; to position: relative;
Set the child <div> width and height to be 100% and remove useless markup.
http://jsfiddle.net/MvPHj/

Categories

Resources