controlling the dimensions of elements html and css - html

I have a header element with 2 elements inside - an img and p elements.
I'd like the header height to be the exact height of the image it contains so that when I remove the margin and padding it "fits".
Rather than adjusting the height of the header element to be the same pixel height as the image, is there a way to "auto" do this?
I have tried height:auto but that just brings unexpected wonky results.
Here's the code:
<header>
<img src="images/logosketch.jpg" alt="companylogo" />
<div class="search">
<p>SEARCH HERE</p>
</div>
</header>
header { position: relative; }
.search { bottom: 0; position: absolute; right: 0; }
.search p { margin: 0; }
Any pointers?

Try the following -
header { position: relative; padding: 0; margin: 0;}
header img {
display: block;
height: 100px;
}
With this method, making the image a block element and manually setting its height, it will cause the parent block element to adjust its size. However, if any other block elements in that header have a greater height than the img element, then it will cause the header to take on that other elements height with the exception of block elements that are position absolute.
Hope this helps.

Remove padding from the container and margin from the image. Some browsers have their own styling on common elements. That's why many people use a CSS Reset stylesheet.
However, if the p element gets bigger, so will the container so you will have to restrict that element in some way (make sure the text does not make it higher than the image or specify the height to be the same as the container.

Related

Elements taking over the space of an element with position absolute

I am trying to have a div at the top of my page that fits with no space against the top and sides.
All the example I have seen on how to do this put the div position to absolute.
But when I do this, the following img sibling moves to the top of the page with the previous div.
So I have two questions. Why does the following sibling move? Also, how can I have a div fit with 0 space against the top, without having position:absolute
div {
position: absolute;
top: 0px;
left: 0px;
background: #888888;
width: 100%;
height: 100px;
}
<body bgcolor="#000000">
<div>
<h1>HEADER</h1>
</div>
<img src="pic_mountain.jpg" alt="Mountain View" style="width:304px;height:228px;">
</body>
</html>
You don't need position: absolute to align things to top just use margin: 0 on the body, h1 Like:
body, h1 {
margin: 0;
}
Have a look at the snippet below:
body, h1 {
margin: 0;
}
div {
background: #888888;
width: 100%;
height: 100px;
}
<!DOCTYPE html>
<html>
<body bgcolor="#000000">
<div>
<h1>HEADER</h1>
</div>
<img src="http://placehold.it/304x228" alt="Mountain View" style="width:304px;height:228px;">
</body>
Hope this helps!
When you give an element position: absolute, you remove it from the normal flow of the document. This means that it no longer takes up any space in the layout. As a result, surrounding elements don't know it exists and take over the previously used space.
But you don't need absolute positioning in this case. The reason for the gaps are default margins on elements set by the browser. Just override those defaults with your own settings.
body, h1 {
margin: 0;
}
div {
height: 100px;
background: #888888;
}
<body bgcolor="#000000"bgcolsor="#000000">
<div>
<h1>HEADER</h1>
</div>
<img src="pic_mountain.jpg" alt="Mountain View" style="width:304px;height:228px;">
</body>
More information:
Normal flow ~ MDN
Absolute positioning ~ MDN
Why does the following sibling move?
It moves to the top because the first div is position: absolute, that's what expected when we apply this property / value. This div is also relative to the parent / body and the whole document (because no position: relative was specified anywhere else). When you apply position: absolute you remove that element from the normal document flow. It kind of flies over the document.
When you have this option applied to an element nested to something using position: relative, you'll see that the child will obey the parent's top, left, right and bottom.
Also, how can I have a div fit with 0 space against the top, without having position:absolute
This way:
body {
margin: 0;
}
With:
h1 {
margin-top: 0;
}
Or:
div {
overflow: hidden;
}
Without position: absolute; top: 0px; left: 0px; width: 100%; on the div. div's default params will take over what's needed.
The margin-top: 0 or overflow: hidden must be there just to get rid of the top h1's default margin, because when there's a margin in a case like that, the div background won't follow the whole div flow. Using overflow: hidden the way I've shown you is a technique of "clearing" things, like clearfix and others. You can read more about them here.
Also, Michael_B links about normal flow and absolute positioning are very relevant and a must read.

div with inline-block not resizing

I have two elements, both with display: inline-block, and the parent has white-space: nowrap.
When the screen is resized, the div on the right side don't resize, like this.
I'm trying to make only the blue div resize.
Full source (jsfiddle)
The structure of the html is like this:
<div class="container">
<div class="header">...</div> <!-- red -->
<div class="aside">...</div> <!-- pink -->
<article>...</article> <!-- blue -->
</div>
Relevant css:
* {
box-sizing: border-box;
}
div.container {
margin: 0 auto;
max-width: 40em;
padding: 0;
white-space: nowrap;
}
div.container > * {
white-space: normal;
}
.aside {
display: inline-block;
max-width: 15em;
vertical-align: top;
}
.article {
display: inline-block;
max-width: 25em;
}
Old question, but for the sake of knowledge of anyone who reads this and also has the doubt:
What I've found is that setting position: relative on the .container
and position: absolute on the .article does what I want.
An absolute positioned element is positioned relative to the nearest positioned ancestor, where a positioned element means anything with a position property different to static, the default; if does not found any positioned element, uses the body element.
The absolute positioned elements, if has their width and heigth in auto, resizes to fit its content, and limits the maximun sizes by its positioned ancestor. You can check this putting a short string instead a large one: the element will shrink to the length of text. If you remove the positioning from div.container, the article (if still positioned absolute) will grow (depending on its content) to cover the space between previous element and body width.
And, related to the aforementioned and to add some utility to this delayed answer, a not-very-know bonus: if you define the right and left properties of a absoluted positioned element, and leave the width in auto, the element will cover the horizontal size between the right and left defined. This way you could put something like
article {
background-color: #a0f4ec;
display: inline-block;
position: absolute;
right: 0;
left: 30%;
}
div.aside {
background-color: #faf;
display: inline-block;
max-width: 15em;
width: 30%;
}
This trick also applies in a vertical sense, but with height, top and bottom properties.
There are a few ways to do it.
Method 1:
two divs the same line, one dynamic width, one fixed
Method 2 (negative margins)
http://alistapart.com/article/negativemargins
Unfortunately, Narxx's answers require the divs to be floated. I'm sure that's what you should do if you're building a real site, but in my case, I'm trying not to use it.
What I've found is that setting position: relative on the .container and position: absolute on the .article does what I want.
Simplified fiddle
If anyone can explain why, I'll mark it as an answer.

Lack of outermost margin with smaller viewport

I have a <div id="wrapper"></div>​ with
#wrapper {
height: 300px;
margin: 10px;
position: absolute;
top: 0;
left: 0;
width: 400px;
}​
When I resize the viewport so that horizontal scrollbars appear, the right margin disappears; I can only scroll as far right at the element's content, but I want the margin to be present on all sides. It also happens to the left margin if right: 0; is applied, and to the bottom margin if the viewport is made shorter. Giving wrapper a position: static; (default) makes no difference.
Why is this happening? It doesn't follow normal margin collapse rules. How can I get my margin back? I've tried giving the body padding/margin.. nada.
jsFiddle
Background Info
The default width of the body element is the html width which is also the window width (or iframe width in such a case). The default behavior of a block level element is that the scroll only accounts for the actual element (hence, it doesn't care about the right margin if there is nothing more to display on the right). This causes your right margin issue. (By the way, according to this article, the scroll bars are actually appearing on the html element, not the body.)
For Position: Absolute
By having #wrapper with position: absolute, the body element ends up with zero height. This causes your bottom margin issue in this case.
A solution is to account for the margins like so (see fiddle):
body {
min-height: 320px;
min-width: 420px;
}
This assigns a minimum dimension to the body equal to the width + margins and height + margins of the absolute element.
Now, I'm not sure what you expect to happen if you have right: 0 set, as forcing a left margin to "remain" just ends up causing, in my opinion, a premature scroll bar to activate. See this fiddle.
Regarding Position: Static
The default block level behavior can be changed by forcing a shrink-wrap like behavior on the body element using (see fiddle):
body { display: inline-block; }
Note: that body { float: left; } did not give me the same shrink-wrap behavior (see fiddle).
The inline-block element will account for the margin of its inner elements to determine its own width, which then allows the right margin to work.
The reason the display: inline-block; solution does not work on the #wrapper being position: absolute is because it makes the body have a zero width and height, since the absolute positioning takes that element out of flow and there is nothing left inside body to give it dimension.
The above was currently only tested on IE9.
I'm afraid there's only one simple and quick solution, and that is to create a new div inside the wrapper div.
http://jsfiddle.net/QHKmN/2/
CSS
#wrapper {
background: black;
height: 300px;
margin: 10px;
position: absolute;
top: 0;
left: 0;
width: 400px;
}
#inwrapper {
background: green;
height: 290px;
margin: 5px auto;
position: relative;
width: 390px;
}
​
HTML:
<div id="wrapper">
<div id="inwrapper">
</div>
</div>
​
And there's your margin.

Place a footer with Content positioned as absolute

I have a wrapper class that contains all the content on the web page. the problem is if the content is absolutely placed, it eats my footer. I have to place the content as absolute positioned.
It seems like the footer doesnot recognize that the content is absolute. Heres my code
<style>
* {
margin: 0;
}
html, body {
height: 100%;
}
.wrapper {
min-height: 100%;
height: auto !important;
height: 100%;
margin: 0 auto -4em;
}
.footer, .push {
height: 4em;
}
</style>
</head>
<body>
<div class="wrapper">
<img src="activity/Chrysanthemum.jpg" style="z-index: 1; position:absolute; width: 420px; height: 400px; left: 100px;top:260px; ">
<div class="push">
</div>
</div>
<div class="footer" >copyrights</div>
</body>
If I change the image style by removing the position:absolute property , everything looks normal. so my question is how can we place the footer at the bottom with absolute positioned contents?
Updated answer, regarding comment.
As I mentioned at my previous answer, this effect cannot be achieved using pure CSS. So, I will show the JavaScript approach. Add relevant IDs (see Fiddle), and add the following code at the end of your body. This code snippet will resize your wrapper when necessary.Note: When the page is smaller than the window's height, the page wrapper will still take the full height, because it's not possible to distinguish a height change by an absolutely positioned element.
<script>
(function(){
var wrapper = document.getElementById("wrapper");
var height = document.documentElement.scrollHeight;
wrapper.style.height = height + "px";
})();
</script>
Previous answer:
The issue is caused by the fact that absolutely-positioned elements do not affect the height/width of their parent.
To fix your code, apply the following CSS (only showing relevant CSS, updated postfixed by descriptive comments). Fiddle: http://jsfiddle.net/4ja2V/
html, body {
height: 100%;
width: 100%;
padding: 0; /* Get rid off the padding */
}
.wrapper {
position: relative; /* Necessary to properly deal with absolutely positioned
child elements. */
height: 100%;
margin: 0 auto 4em; /* So that the content is visible when scrolled down*/
}
.footer {
height: 4em;
position: fixed; /* Positions your footer at a fixed position in the window*/
bottom: 0; /* At the bottom of the window*/
}
You were using a negative bottom-margin for .wrapper, which caused the element to "eat" the footer. When you're using absolutely poisitioned inner elements, there's no reliable pure-CSS method to get the real width/height of the .wrapper element. Hence the appearance of position:fixed.
The footer is defined to have a height of 4em. Because the footer is positioned at a fixed position (ie, the element won't move when scrolling down), it's necessary to apply an additional margin at the bottom of the wrapper element.
give your footer a fixed hight and then in your absolute class, do
bottom: heightOfYourFooter + 5px;

Div on top of Div using z-index

I have the following divs in my HTML:
<div class="main">
<div class="bgimage"></div>
<div class="content">Text</div>
which is directly inside my body.
With the following CSS:
body {
margin: 0;
padding: 20px 0;
}
.content {
filter: alpha(opacity=50);
-moz-opacity: 0.5;
opacity: 0.5;
}
.content {
position: relative;
z-index: 1;
border: #000 thin solid;
width: 960px;
margin-left: auto;
margin-right: auto;
background-color: #000;
}
.bgimage {
position: absolute;
z-index: -1;
width: 1024px;
height: 768px;
margin-left: auto;
margin-right: auto;
background-image: url(bg1.jpg);
}
Basically, I have a Div that with a display of a background image, and I will have another Div on top of this with transparency. This current code works, but my problem is when I am trying to take the content div down from the top.
When I add margin-top:100px, for example, is also brings the image down. I thought it would not touch it if it is not on the same z-index? Why does adding a margin also force the bgimage div down?
I have also tried making the div with class of content a position of absolute and a zindex, but then this won't centre. How should I solve this?
your CSS should be
.bgimage { position: relative; }
.content { position: absolute; }
so the .content will be positioned relative to the .bgimage
your current CSS makes the .bgimage position relative to the document.
see this link on CSS positioning
z-index has no relation to positioning: it only affects the rendering order of your elements. Position: relative tells the browser to render the element at the place it should be, and offset it by eventual left, right, top or bottom coordinates. Therefore, margins, paddings, etc. still affect it.
Only position: absolute guarantees position independance.
I see no need for "z-index"es or "position: absolute" in your code at all -- unless you have other complications that you have not revealed to us.
To center the background on the DIV class="main":
body{margin:0;padding:20px 0;}
.main{background:transparent url(bg1.jpg) no-repeat center top;}
.content{border:#000 thin solid;width:960px;margin-left:auto;margin-right:auto;background-color:#000;opacity: 0.5;filter:alpha(opacity=50);-moz-opacity: 0.5;}
The "center top" places the center-top of the background image on the center-top of the element it's applied to. You may want to apply a
min-width:1024px;_width:1024px;
to the same element -- to prevent a narrower window from hiding the edges (this will change how the element is rendered if the "viewport" is narrower than the background's dimensions).
The only thing your pre-modified code it can do that my modified code can't:
Crop the background image (if it is not natively 1024px x 768px) by using the css "width" and "height" properties
If the class="main" element already has a background image set, most browsers don't support the CSS3 required to stack multiple backgrounds on the same element
Some of what was stated about "z-indexing" and the "position" property above was correct but failed to mention:
you've taken your class="content" element out of "the flow". The ancestor elements won't grow when the content of class="content" element grows. This is an important and fundamental difference between "z-index"ed elements and elements that remain "in the flow".
Other side notes:
elements with the same z-index are stacked according to their order in the HTML (later in the HTML means they are drawn above on the screen)
"z-index"ing requires "position: (absolute|relative)", "z-index: (valid value)", and IIRC "(top|left|bottom|right): (valid value)" to take the element "out of the flow"
CSS absolute positioning is always done "relative" to the most recent ancestor that has a "position: relative", otherwise it uses the body tag by default. If the CSS you included is all that affects those divs, then your .content div will be positioned relative to the .main div, but your .bgImage will be positioned based on the tag.
If you want both .content and .bgImage to move in lockstep, then you'll need to add a "position: relative" to div.main.