Javascript positioning center style - javascript

I wanted to set my second div element indside of my first div element center. I think somehow I managed to center it. But I think I made some mistakes and it seems to me it is not properly centered and also this JavaScript style seems to me bad. Is there any better way doing it? Is my JavaScript code is correct?
FIDDLE
HTML
<div class='first'>
<div class='second'>
</div>
</div>
JavaScript
var first = document.getElementsByClassName('first')[0];
var second = document.getElementsByClassName('second')[0];
var height = first.offsetHeight;
second.style.width = height/2+"px";
second.style.height = height/2+"px";
second.style.marginLeft = height/4+"px";
second.style.marginTop = height/4+"px";

offsetHeight will get the height of the element including borders, clientHeight won't. Instead of:
var height = first.offsetHeight;
Try:
var height = first.clientHeight;
JSFiddle
I've also used top and left with position:absolute for positioning, as this take the element out of the page flow and I assume this is the behaviour you are looking for.
References:
offsetHeight
clientHeight
(Follow the links and take a look at the box-model diagrams)

Reason is drawing round take 3px thats why not positioning but you divide 2.1 that result come that you need.
Check this Demo jsFiddle
JavaScript
var first = document.getElementsByClassName('first')[0];
var second = document.getElementsByClassName('second')[0];
var height = first.offsetHeight;
second.style.width = height/2.1+"px";
second.style.height = height/2.1+"px";
second.style.marginLeft = height/4+"px";
second.style.marginTop = height/4+"px";

var second = document.getElementsByClassName('second')[0];`
var left = (screen.width/2)-(100/2);
var top = (screen.height/2)-(100/2);
second.style.width = "100px"; //set as per your requirement
second.style.height = "100px"; //set as per your requirement
second.style.left= left +"px";
second.style.top = top +"px";

Just in case, you're interested, I tried to come up with a CSS only solution.
http://jsfiddle.net/53M6A/1/
Here's the changes I made to the .second class.
.second{
left: 50%; //move 50% to left
top: 50%; // move 50% down
margin-left: -50px; //move half of it's own size back to the left
margin-top: -50px; //move half of it's own size back to the top
position: relative; //make it relative, so it can be moved around by left/top
width:100px;
height:100px;
background: #fff;
border-radius:50%;
}

I've been playing a little in your fiddle and finally, I changed your 2 last lines for these:
first.style.display = "table-cell";
first.style.verticalAlign = "middle";
second.style.margin = "0 auto";
Fiddle
Seems perfectly centered to me.

Related

Highlighting line of text in div while scrolling

I'm trying to highlight some text in a div, with the highlight being a fixed line in said text. So far I've got a very simple solution that uses two divs, one that houses the text, and the other acting as the highlight, and as you scroll the text, it will pass through the highlight div.
HTML is as follows:
<div id="test">
text...
</div>
<div id="highlight"></div>
CSS is:
#highlight {
position: fixed;
top: 50%;
width: 100%;
background-color: #ccff00;
height: 30px;
opacity: 0.6;
}
#test{
position: absolute;
font-size: 30px;
top: 50%;
}
A demo of it can be found here
I was wondering if anyone knows how to make it so that scrolling the text can be done in a way where as a user scrolls, the next line becomes highlighted. Currently it scrolls normally, so the highlight may miss a line, or not highlight a complete line. Additionally, I was wondering how it would be best to make the text scroll all the way to the bottom. Would adding a margin of the same size as the offset at the top work? Alternative solutions for any of this would be appreciated as well.
Try adding an event listener to the window on scroll. Then calculate the offset by taking the scrollY % line-height and set the highlight top margin to the negative of that value.
JavaScript below:
var highlight = document.querySelector("#highlight");
window.addEventListener('scroll', function(e){
var y = window.scrollY;
var offset = y % 30;
highlight.style.marginTop = - y % 30 + "px";
});
See Working Fiddle
Not sure if this
https://jsfiddle.net/ok0x3apo/6/ is what you're looking for
You can see that I'm remodifying the entered text, to get line by line highlight as page scrolls.
var el = document.getElementById("text"),
content = el.innerHTML.replace(/ |^\s+|\s+$/g,""),
lines = content.split(/\./);
var html = "";
for(var i in lines){
html+="<p class='clear_display' id='id_"+i+"'>"+lines[i]+".</p>";
};
document.getElementById("text").innerHTML=html;
You can make changes to the "clear_display" class on how you prefer to have the text block.
function calledEveryScroll() {
var scrollPosition = $(window).scrollTop();
for(var i in lines){
var currentSection = document.querySelector("#id_"+i+"");
var sectionTop = currentSection.offsetTop;
if (scrollPosition<=0){
$(".clear_display").removeClass('active');
document.querySelector("#id_0").className += " active";
}
if (scrollPosition >= sectionTop-50) {
$(".clear_display").removeClass('active');
if (!$(currentSection).hasClass('active')) {
$(currentSection).addClass('active');
if(previous){
if(currentSection.offsetTop==previous.offsetTop){
$(previous).addClass('active');
}
}
var previous = currentSection;
}
//return false;
}
}
}
function resizing(){
var offset =100;
var bottom = $(window).height()-offset;
$('#text').css('margin-bottom',bottom);
}
This function checks each line when page scrolls.For the scroll to reach the bottom I'm calculating the margin-bottom.Hope it helps.

How to set a dynamic CSS value with JavaScript

I want to have responsive padding for a div on my page.
It should be a fifth of the height of itself, which is in the variable cover_height.
This is my approach so far, which is following an answer to this question,
but it doesn't change padding-top:
var cover = document.getElementById("cover");
var cover_height = cover.height;
cover.style["padding-top"] = cover_height / 5 + "px";
Any feedback regarding the code is welcome as I am pretty new to JS.
JavaScript (vanilla) has no element.height function as far as I know. It should be .clientHeight or .offsetHeight depending on what you are looking for. offsetHeight returns the height including the border, padding and scroll bars.
var cover = document.getElementById("cover");
var cover_height = cover.clientHeight;
cover.style["padding-top"] = cover_height / 5 + "px";
#cover {
height: 300px;
background: red;
}
<div id='cover'></div>
Does this approach to responsive design make sense?
If you could use fixed viewport unit based value for height then I would recommend something like in the below snippet. Here the height of the element increases (or decreases) based on the height of the viewport and the padding-top is always 1/5th of the height. For example, if viewport height is 100px, the element's height would be 30px and the padding top would be 6px.
#cover {
height: 30vh;
background: red;
padding-top: 6vh;
}
<div id='cover'></div>
If you cannot use viewport units (or) the element's height is auto and will increase or decrease based on content then your approach is reasonably good for setting padding-top.
If you had wanted to set padding-top based on the width of the element's parent then I would have recommended doing it with pure CSS using percentage values. This is because a percentage value for padding or margin is always computed with respect to the element's width. An exampe of this behavior is available here.
Working fiddle
You should use clientHeight or offsetHeight instead of height.
clientHeight : includes the height and vertical padding.
offsetHeight : includes the height, vertical padding, and vertical borders.
Example :
var cover = document.getElementById("cover");
var cover_height = cover.clientHeight;
//OR
var cover_height = cover.offsetHeight;
cover.style.paddingTop = cover_height / 5 + "px";
Hope this helps.
var cover = document.getElementById("cover");
var cover_height = cover.clientHeight;
cover.style.paddingTop = cover_height / 5 + "px";
#cover{
width: 200px;
height: 200px;
background-color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='cover'> Cover </div>

Drawing Lines Behind Divs

I am looking at this fiddle:
http://jsfiddle.net/kDs2Q/45/
Is there a way to layer the divs/line in a way so that the line will be behind the other divs? I want to be able to draw the line from the center of one div to the center of the other but not see the line cross over the actual boxes.
This is how I would to the center-to-center:
var off1 = getOffset(div1);
var off2 = getOffset(div2);
var x1 = off1.left + off1.width/2;
var y1 = off1.top + off1.height/2;
var x2 = off2.left + off1.width/2;
var y2 = off2.top + off1.height/2;
Yes use z-index in your style.
z-index:-1
JSFiddle http://jsfiddle.net/D24uC/
Use z-indexes, the DIVs need to have a higher z-index than the 'line-div'.
Give it a try, set the DIVs z-index to 1000 or something and see the result:
http://jsfiddle.net/kDs2Q/884/
<div id="div1" style="position:absolute; z-index:1000; background-color:blue; width:100px; height: 200px;top: 200px; left: 100px;">

how to center and make various images sizes fit in a container

I'm using bxslider to have a carousel of images. The thing is though, the images it receives to display are of somewhat unpredictable sizes. The container size is 243x243. And we know that no image will have a side smaller than 243. So...I'd like to center the image in the container. And either zoom in until the shorter of the two dimensions (L vs W) fills the container at 243, and the longer dimension overflow is hidden.
For the images I'm working with, doing this will be perfect for getting the important details of the picture in the frame.
But I'm having trouble...
I've tried the following to center the picture in the frame:
jQuery(".bx-container").each(function() {
var img_w = jQuery(this).children("img").width();
var img_h = jQuery(this).children("img").height();
var pos_top = (img_h - containerHeight) / 2;
var pos_left = (img_w - containerWidth) / 2;
var pos_top = (243 - img_h) / 2;
var pos_left = (243 - img_w) / 2;
jQuery(this).children("img").css({
'top' : pos_top + 'px',
'left' : pos_left + 'px'
});
});
And I've tried this to position not square images into the frame:
jQuery(".bx-container").each(function(){
var refRatio = 1;
var imgH = jQuery(this).children("img").height();
var imgW = jQuery(this).children("img").width();
if ( (imgW/imgH) < refRatio ) {
jQuery(this).addClass("bx-portrait");
} else {
jQuery(this).addClass("bx-landscape");
}
});
});
I've messed with both scripts and the css but I just can't seem to get it work. It either centers but doesn't resize right. Or resizes but centers wrong. Or does both wrong.
Here's the jsfiddle: http://jsfiddle.net/vgJ9X/298/
Could someone help me out?
Thanks!
EDIT:
New jsfiddle...the portrait ones work right. The landscape images still squish. :(
http://jsfiddle.net/vgJ9X/307/
EDIT:
I THINK it has something to do with relatively positioned elements not being allowed to overlap. Trying to find a fix. If anyone knows, edit the last fiddle I posted.
jQuery(".bx-container img").each(function () {
var w = jQuery(this).width();
var h = jQuery(this).height();
if (w > h) $(this).addClass('bx-landscape');
else $(this).addClass('bx-portrait');
});
Check this Updated JSFiddle
Update
jQuery(".bx-container img").each(function () {
var w = jQuery(this).width();
var h = jQuery(this).height();
if (w > h){
$(this).addClass('bx-landscape');
var trans= -243/2;
$(this).css('-webkit-transform','translateZ('+trans+'px)');
}
else if(h > w){
$(this).addClass('bx-portrait');
var trans= -243/2;
$(this).css('-webkit-transform','translateY('+trans+'px)');
}
});
check this JSFiddle
Update of Update
Found the issue with landscape, the plugin is setting max-width:100%; overriding it with max-width:none; fixes the issue...
Update Of Updated Fiddle
Try this:
img{
position:relative;
height:100%;
width:300px;
}
Simple an clean.
Demo: http://jsfiddle.net/vgJ9X/302/
I did a couple things to your jsfiddle.
First I changed the order of your resize and center functions, so the resize comes first. This way, the smaller images get resized, then centered. I also uncommented the first portion of your code.
You also had a couple of errors in your css. There was an extra closing bracket after img style declaration. Your .bx-portrait img and .bx-landscape img declarations were set to 100%px;.
Update:
Change the css in your two .bx classes to:
.bx-portrait img {
height: 100%;
width: auto;
}
.bx-landscape img {
height: auto;
width: 100%;
}
And add a clearfix to your ul:
.bxslider:after {
content: '';
clear: both;
display: table;
padding: 0;
margin: 0;
}
The height is clipping because .bx-viewport has a set height of 243px but also has a 5px border, which makes the actual internal height 233px. You'll need to make the height 253px to account for the 10px of border. This is why they don't look centered vertically.
DEMO
Why don't you just use background images instead and center them. Here is a demo from your original code
http://jsfiddle.net/8y8df/
If you want to show the full size image, just remove the background-size:contain; from the css.

CSS: Child div overlapping parent

I have something vaguely like the following:
<div id="body">
surrounding text
<div id="pane" style="overflow: auto; height: 500px; width: 500px;">
lots and lots of text here
<span id="some_bit">tooltip appears below-right of here</span>
</div>
more surrounding text (should be overlapped by tooltip)
</div>
and:
<div id="tooltip" style="width: 100px; height: 100px;">Whee</div>
What I want to do is insert the tooltip such that it is positioned above the pane it's in. If it's attached to an element that's next to the pane boundary (like above), then it should be visible above the pane, and above the text surrounding the pane.
It should NOT a) extend the pane, such that you have to scroll down to see the tooltip (like in http://saizai.com/css_overlap.png), or b) be cut off, so you can't see all of the tooltip.
I'm inserting this with JS, so I can add a wrapper position:relative div or the like if needed, calculate offsets and make it position:absolute, etc. I would prefer to not assume anything about the pane's position property - the tooltip should be insertable with minimal assumptions of possible page layout. (This is just one example case.)
It's for a prototype tooltip library I'm writing that will be open source.
ETA: http://jsfiddle.net/vCb2y/5/ behaves visually like I want (if you keep re-hovering the trigger text), but would require me to update the position of the tooltip on all DOM changes and scrolling behavior. I would rather the tooltip be positioned with pure CSS/HTML so that it has the same visual behavior (i.e. it overlaps all other elements) but stays in its position relative to the target under DOM changes, scrolling, etc.
ETA 2: http://tjkdesign.com/articles/z-index/teach_yourself_how_elements_stack.asp (keep defaults except set cyan div 'a' to position:relative; imagine 'A' is the pane and 'a' the tooltip) seems to more closely behave as I want, but I've not been able to get it to work elsewhere. Note that if you make 'A' overflow: auto, it breaks the overlapping behavior of 'a'.
I can't think of a pure HTML/CSS solution for this.
The overflow declaration is the issue here. If the tooltip is in #pane:
you establish a positioning context within #pane, then the tooltip shows next to #some_bit (regardless of scrolling, etc.) but it gets cut-off.
you do not establish a positioning context, then the tooltip is not clipped but it has no clue where #some_bit is on the page.
I'm afraid you'll need JS to monitor where #some_bit is on the page and position the tooltip accordingly. You'd also need to kill that tooltip as soon as #some_bit is outside of the viewing area (not an issue if the trigger is mouseover).
Actually, if the trigger is mouseover then you may want to use the cursor coordinates to position the tooltip (versus calculating the position of #some_bit).
I would just put the tooltip outside of the #pane div and position it absolutely using JavaScript since you're using JS anyway.
I don't use Prototype so I don't know how it's done in Prototype, but in jQuery, you'd use $(element).position() to get the element position. If you have to do it manually, it's a little more complicated.
And you'll probably want to add a little extra logic to prevent the tooltip from extending outside of the document.
Edit: CSS used
#tooltip {
z-index: 9999;
display: none;
position: absolute;
}
JS used
Note: in jQuery, but it should be easy to change it to Prototype syntax.
$('#some_bit').hover(function() {
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
// hovered element
var offset = $(this).offset();
var top = offset.top + docViewTop;
var left = offset.left;
var width = $(this).width();
var height = $(this).height();
var right = left + width;
var bottom = top + height;
// pane
var poffset = $('#pane').offset();
var ptop = poffset.top + docViewTop;
var pleft = poffset.left;
var pwidth = $('#pane').width();
var pheight = $('#pane').height();
var pright = pleft + pwidth;
var pbottom = ptop + pheight;
// tooltip
var ttop = bottom;
var tleft = right;
var twidth = $('#tooltip').width();
var theight = $('#tooltip').height();
var tright = tleft + twidth;
var tbottom = ttop + theight;
if (tright > pright)
tleft = pright - twidth;
if (tbottom > pbottom)
ttop = pbottom - theight;
if (tbottom > docViewBottom)
ttop = docViewBottom - theight;
$('#tooltip').offset({top: ttop, left: tleft});
$('#tooltip').css('display', 'block');
}, function() {
$('#tooltip').hide();
});
Edit: See it here.

Categories