What default CSS is preventing me from fully overlapping two elements with relative positioning? - html

Why don't #img1 and #canvas1 fully overlap in the below code? I want them in exactly the same place. I'm layering images with JavaScript animation on canvas. Initial thoughts were that the padding or margin default settings were interfering somewhere. I've tried setting to zero for all elements - it doesn't work. I understand that position:relative positions an element relative to it's normal position. Clearly missing a default setting or something obvious.
<!DOCTYPE html>
<html>
<head>
<style>
.chapter {
width: 90%;
margin: 0 auto;
max-width: 1000px;
border: 1px solid red;
}
#img1 {
border: 1px solid green;
position: relative;
left: 50px;
height: 100px;
width: 100px;
margin: 0px;
padding: 0px;
}
#canvas1 {
border: 1px solid blue;
position: relative;
left: -50px;
height: 100px;
width: 100px;
margin: 0px;
padding: 0px;
}
</style>
</head>
<body>
<div class="template" id="T2">
<div class="chapter" id="C2">
<h1>Why can't I overlap the below elements?</h1>
<img src="" id="img1" />
<canvas id="canvas1"></canvas>
</div>
</div>
</html>

Two things to do:
1.) Don't leave a linebreak or space between the two elements in the HTML code (see below)
2.) Set the left setting for canvas to -52px - you have to consider the 2 x 1px border of the image.
.chapter {
width: 90%;
margin: 0 auto;
max-width: 1000px;
border: 1px solid red;
}
#img1 {
border: 1px solid green;
position: relative;
left: 50px;
height: 100px;
width: 100px;
margin: 0px;
padding: 0px;
}
#canvas1 {
border: 1px solid blue;
position: relative;
left: -52px;
height: 100px;
width: 100px;
margin: 0px;
padding: 0px;
}
<div class="template" id="T2">
<div class="chapter" id="C2">
<h1>Why can't I overlap the below elements?</h1>
<img src="" id="img1" /><canvas id="canvas1"></canvas>
</div>
</div>

A couple of remarks:
use box-sizing: border-box for 'easier' sizing. With border-box the border width and padding are substracted from the elemenent istead of added on to it. An element with width: 100px, a border-width of 1px and a padding of 10px will be 100 + (2 * 1) + (2 * 10) = 122px wide without box-sizing: border-box but the element will be 100px wide even with the border-width and padding when the box-sizing is set to border-box. See here for a (better) more detailed explanation: https://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing
When trying to overlap element I find it easiest to keep the surrounding container element as empty as possible. Taking out the h1 element makes overlapping a lot more manageable.
Change the position of the canvas element to absolute. This way it no longer takes up place in the DOM and it is positioned in the upper left container of its positioning parent (in your example the div.chapter in my answer the div.container). This also helps when trying to have elements line up.
* {
box-sizing: border-box;
}
.container {
position: relative;
}
.chapter {
width: 90%;
margin: 0 auto;
max-width: 1000px;
border: 1px solid red;
}
#img1 {
border: 1px solid green;
position: relative;
left: 50px;
height: 100px;
width: 100px;
margin: 0px;
padding: 0px;
}
#canvas1 {
border: 1px solid blue;
position: absolute;
left: 50px;
height: 100px;
width: 100px;
margin: 0px;
padding: 0px;
}
<div class="template" id="T2">
<div class="chapter" id="C2">
<h1>Why can't I overlap the below elements?</h1>
<div class="container">
<img src="" id="img1" />
<canvas id="canvas1"></canvas>
</div>
</div>
</div>

#img1 {
border: 1px solid green;
position: relative;
left: 56px;
height: 100px;
width: 100px;
margin: 0px;
padding: 0px;
}
this worked...

There are certainly better ways to achieve the effect you're going for but to answer your question, I believe the spacing is being caused by the default font size on the parent element. Set the font size to 0px on the chapter div and you can see the elements now overlap each other.

Related

Why the div preview, despite his position is set on relative appears inside the other div?

I am gonna to copy paste all the code, so you can check everything and understand what it's the problem. Thank you.
I just wanted to make it appear under the previously div. Just like it shoud be, because this problems not only appears with this div, but with everything else.
.presentazione
{
position: relative;
top: 100px;
width:auto;
height:auto;
text-align: center;
font-size:30px;
border: 2px solid red;
}
.sottofondo
{
position: relative;
display: inline-flex;
width: auto;
height: auto;
border: 2px solid grey;
}
.messaggio
{
position: relative;
width: auto;
height: auto;
border: 1px solid green
}
.sottofondo .icona
{
position: relative;
width: auto;
height: auto;
border:1px solid pink;
}
.preview
{
position: relative;
width: auto;
height: auto;
}
<div class="presentazione"> MESSAGE </br> OTHERS THINGS, BLA BLA BLA
<div class="sottofondo">
<div class="messaggio"> ANOTHER THING </div>
<div class="icona"> <img src="Icons/CuoreV.png" style="width:30px; height:30px;"/></div>
</div>
</div>
<div class="preview"> PROBLEM HERE </div>
Your problem if I understood correctly is that you have on your presentazione element the top property which this makes the element to move 100px from the top of the page without pushing the other elements.
If you want it to have a 100px distance from top better use margin-top: 100px.
I removed the top property from that class and it seems to be correct. Check it out below:
.presentazione {
position: relative;
width: auto;
height: auto;
margin-top: 100px; /* changed from top to margin-top */
text-align: center;
font-size: 30px;
border: 2px solid red;
}
.sottofondo {
position: relative;
display: inline-flex;
width: auto;
height: auto;
border: 2px solid grey;
}
.messaggio {
position: relative;
width: auto;
height: auto;
border: 1px solid green
}
.sottofondo .icona {
position: relative;
width: auto;
height: auto;
border: 1px solid pink;
}
.preview {
position: relative;
width: 200px;
height: 200px;
}
<div class="presentazione"> MESSAGE </br> OTHERS THINGS, BLA BLA BLA
<div class="sottofondo">
<div class="messaggio"> ANOTHER THING </div>
<div class="icona"> <img src="Icons/CuoreV.png" style="width:30px; height:30px;"/></div>
</div>
</div>
<div class="preview"> PROBLEM HERE </div>
Your .presentazione div's position is set to relative and its top:100px, so other elements are behaving like its still in its original position, therefore you see that overlap, you can try margin-top:100px instead of top:100px and it will work.
more info on relative positioning here: https://developer.mozilla.org/en-US/docs/Web/CSS/position

IE with position absolute element will create horizontal scroll

I want to use position: absolute to create a centered element, but it will create a horizontal scrollbar on Internet Explorer 11. Please see the script below. Anyone here knows how to fix this problem?
*Update: I figured out that using overflow:hidden seems to solve this problem somehow. But when there are another one outside of the container, it will be hidden as well.
.container {
width: 80%;
margin: 0 auto;
height: 100vh;
border: 1px solid green;
position: relative;
overflow: hidden; /*This one is not the solution, though*/
}
.content {
width: 80%;
height: 30px;
position: absolute;
top: 50px;
left: 50%;
transform: translate(-50%, 0);
border: 1px solid red;
}
.another-content {
width: 40px;
height: 40px;
border: 1px solid blue;
position: absolute;
bottom: 20px;
right: -20px;
}
<div class="container">
<div class="content"></div>
<div class="another-content"></div>
</div>
You need to add following properties with the position absolute in IE
position: absolute;
top:0;
right: 0;
left: 0;
bottom:0; //specify all including bottom:0
The scrollbar show up in all browsers, not only IE. You can do the following:
The biggest issue is that the left: 50% and width: 80% together are adding to the total width and forcing the horizontal scrollbar to show up in some browsers (e.g. Internet Explorer and MS Edge). You set the width to 80%, so divide the remaining 20% between the left and right border and you'll end up with 10% each. Simply use left: 10% to achieve the same result, but without the side effect of the horizontal scrollbar.
Also when you set the size to 100% and then add border, those borders will be out of the view and cause the scrollbars to show up. This is the same in all browsers. Use box-sizing: border-box to force the browser to include the border in the height and width calculation.
The height: 100vh makes the box height equals to the view port. However, the body has default margins which vary from one browser to another. You can either set those margins to zero body { margin: 0; }, or change the height to height: 100% which is 100% of the container which the body in this case.
Try this:
.container {
width: 100%;
height: 100%;
border: 1px solid green;
position: relative;
box-sizing: border-box;
}
.content {
width: 80%;
height: 30px;
position: absolute;
top: 50px;
left: 10%;
border: 1px solid red;
}
<div class="container">
<div class="content"></div>
</div>
Thanks for your replies. Though they are not direct solution, they helped me a lot to figure out how to solve it.
The cause is as what Racil Hilan said. When I use left:50% and width:80%, the content width will be added up and create a horizontal scroll, which is not ignored by only IE. And my point is to avoid creating that added-up width. Here is my two way to workaround this one.
* {
box-sizing: border-box;
}
.container {
width: 100%;
height: 100vh;
border: 1px solid green;
position: relative;
}
.content {
width: 80%;
height: 30px;
position: absolute;
top: 50px;
left: 0;
right: 0;
border: 1px solid red;
margin: 0 auto;
}
.content-wrapper {
border: 1px solid black;
height: 30px;
position: absolute;
top: 100px;
left: 0;
right: 0;
}
.another-content {
width: 80%;
display: block;
height: 100%;
border: 1px solid red;
margin: 0 auto;
}
<div class="container">
<div class="content"></div>
<div class="content-wrapper">
<div class="another-content"></div>
</div>
</div>

How to ignore parents div center position

The div (page-wrap) is the page container, it has a width of 960px and its position is centered to the middle of the page. I want to have a child div that ignores this and has the width of the page.
.page-wrap {
min-height: 100%;
max-width: 960px;
margin:0 auto;
/* equal to footer height */
margin-bottom: -50px;
}
I want this div to ignore the above
hr {
display: block;
height: 1px;
border: 0;
border-top: 1px solid #ccc;
margin: 0;
padding: 0;
}
HTML
<div class="page-wrap">
<img src="logo.jpg" width="150px" height="75px">
<hr/>
</div>
They are 3 types of positions in CSS :
static
relative
fixed
absolute
In your case, you want to use any of them except absolute. Try and see what fits best for your needs.
read this
You can use position: absolute; only if there isn't any parent element with position:relative, otherwise there is no option to achieve this I guess.
.page-wrap {
min-height: 100%;
max-width: 360px;
margin: 0 auto;
/* equal to footer height */
margin-bottom: -50px;
}
hr {
display: block;
height: 1px;
border: 0;
border-top: 1px solid #ccc;
margin: 0;
padding: 0;
/*added*/
position: absolute;
left: 0;
width: 100%;
}
<div class="page-wrap">
<img src="logo.jpg" width="150px" height="75px">
<hr/>
</div>
Seems hack-ish, but it might work.
Known % width method.
https://jsfiddle.net/eulloa/5308kd5r/2/
hr {
display: block;
height: 1px;
border: 0;
border-top: 1px solid #ccc;
margin: 0;
padding: 0;
/* addition */
margin-left: -33.33%;
margin-right: -33.33%;
}
Source. Includes alternatives.
https://css-tricks.com/full-width-containers-limited-width-parents/

Why does this margin flows outsite its parent?

I have a div mainlogo inside another div for logo. Now, when I give it margin on top, it flows outside the outer divs. What I want is that when I give it margin-top, it should displace itself downward, instead of flowing its margin outside the parent.
.header {
width: inherit;
height: 100px;
background-color: #0080FF;
box-shadow: 0.5px 0.5px 0.5px 0.5px grey;
}
.headerdiv img {
width: 80px;
}
.headerdiv {
width: 1020px;
margin: 0 auto;
height: inherit;
position: relative;
}
#mainlogo {
height: 80px;
width: 350px;
margin-top: 10px;
}
<div class="header">
<div class="headerdiv">
<a href="onlinequiz login.php">
<div id="mainlogo">
<img src="Images/logo.png"></img>
</div>
</a>
</div>
</div>
Why does it happen and how can I solve it?
Tricky margin spec. This page has a very good explanation of the behavior you are running into. If you don't want to change the #mainlogo whitespace to padding, you can work around the margin collapse by giving an overflow: hidden property to your .header.
.header {
width: inherit;
height: 100px;
background-color: #0080FF;
box-shadow: 0.5px 0.5px 0.5px 0.5px grey;
overflow: hidden;
}
.headerdiv img {
width: 80px;
}
.headerdiv {
width: 1020px;
margin: 0 auto;
height: inherit;
position: relative;
}
#mainlogo {
height: 80px;
width: 350px;
margin-top: 10px;
}
<div class="header">
<div class="headerdiv">
<a href="onlinequiz login.php">
<div id="mainlogo">
<img src="Images/logo.png"></img>
</div>
</a>
</div>
</div>
Also, you might consider changing the #mainlogo div into a span and self-closing your img tag to avoid unexpected cross-browser quirks.
beacuse you are using a generalize DIV's as it is. Use floating property i.e. float:left there,
and it will work
like this,
#mainlogo {
float:left;
height: 80px;
width: 350px;
margin-top:20px;
}
Try this ... Set the position property of headerdiv to position: absolute;
.headerdiv {
width: 1020px;
margin: 0 auto;
height: inherit;
position: absolute;
}

How do I crop and center a full-height image when I don't know the container's dimensions?

There are a few questions out there that show how to crop and center images, but I haven't found one that matches these requirements:
The visible part of the image must be square.
The image should be scaled so that the full height is displayed and fills the height of the container.
The size of the container is variable and determined by the width of it's container.
The image must be centered.
The end-goal is to have a grid with 3 square images in a row that shrink depending on the browser width.
Here's what I have so far.
.i-om-section-content {
max-width: 800px;
border: 3px solid blue;
margin: 0 auto;
padding: 0 32px;
padding: 0 3.2rem;
position: relative;
z-index: 2;
}
.i-om-item {
overflow: hidden;
margin: 10px;
position: relative;
width: 32.5%;
height: 0;
padding-bottom: 32.5%;
border: 1px solid;
float: left;
}
img {
position: absolute;
left: -100%;
right: -100%;
top: 0;
bottom: 0;
margin: auto;
min-height: 100%;
min-width: 100%;
}
<div class="i-om-section-content">
<div class="i-om-item">
<img src="http://onetaste.us/wp-content/uploads/2015/10/DSC2641.png" />
</div>
<div class="i-om-item">
<img src="http://onetaste.us/wp-content/uploads/2015/10/smita.png" />
</div>
</div>
JSFiddle
Generally speaking, if you want more advance cropping/positioning/sizing of images, it's much easier to work with them as background images. background-size:auto 100% means "auto width, full height," the rest of it was what you already had.
<div class="i-om-section-content">
<div class="i-om-item one">
</div>
<div class="i-om-item two">
</div>
</div>
--
.i-om-section-content {
max-width: 800px;
border: 3px solid blue;
margin: 0 auto;
padding: 0 32px;
padding: 0 3.2rem;
position: relative;
z-index: 2;
}
.i-om-item {
overflow: hidden;
margin: 10px;
position: relative;
width: 32.5%;
height: 0;
padding-bottom: 32.5%;
border: 1px solid;
float: left;
background-size:auto 100%;
background-size:center center;
}
.one{
background-image:url("http://onetaste.us/wp-content/uploads/2015/10/DSC2641.png");
}
.two{
background-image:url("http://onetaste.us/wp-content/uploads/2015/10/smita.png");
}
https://jsfiddle.net/ammsh4y5/
See this updated fiddle.
It uses jQuery to set the height and width of the container to be the same (make it square). It then sets the image height to the height of the div. Lastly, it centers the image by getting the difference of the widths of the image and the div, dividing it by two, and moving it that much left (absolute positioning).
Here's the jQuery code (CSS and HTML were modified as well):
function updateImage() {
$("img").each(function() {
var parent = $(this).parent();
parent.height(parent.width());
$(this).height(parent.height());
$(this).css("left", -($(this).width()-parent.width())/2);
});
}
// call on window resize and on load
$(window).resize(function() {
updateImage();
});
updateImage();
It's not the most elegant solution but it does the job and is pretty intuitive. (But I do like #DylanWatt's background-image solution: much more creative).
.i-om-section-content {
max-width: 800px;
border: 3px solid blue;
margin: 0 auto;
padding: 0 32px;
padding: 0 3.2rem;
position: relative;
z-index: 2;
}
.i-om-item {
overflow: hidden;
margin: 10px;
position: relative;
width: 32.5%;
height: 0;
padding-bottom: 32.5%;
border: 1px solid;
display:inline-block;
background-position:center center;
}
.one{
background-image:url("http://onetaste.us/wp-content/uploads/2015/10/DSC2641.png");
}
.two{
background-image:url("http://onetaste.us/wp-content/uploads/2015/10/smita.png");
}
<div class="i-om-section-content">
<div class="i-om-item one">
</div>
<div class="i-om-item two">
</div>
</div>