button position absolute not working as expected - html

Can anyone explain why this button is not absolute-positioned to the right? I would expect it to be 3px from every edge.
HTML:
<div class="wrapper">
<button>Hello world</button>
</div>
CSS:
.wrapper {
height: 300px;
width: 300px;
background-color: #f33;
position: relative;
}
.wrapper button {
position: absolute;
top: 3px;
bottom: 3px;
left: 3px;
right: 3px;
}
Also, how is it that the button is able to align its contents vertically?

button, like most form elements, is a replaced element. Replaced elements behave differently from regular non-replaced elements (such as div) when absolutely positioned. The following two points from section 10.3.8 of CSS2.1 apply:
The used value of 'width' is determined as for inline replaced elements. If 'margin-left' or 'margin-right' is specified as 'auto' its used value is determined by the rules below.
...
If at this point the values are over-constrained, ignore the value for either 'left' (in case the 'direction' property of the containing block is 'rtl') or 'right' (in case 'direction' is 'ltr') and solve for that value.
The width of the button is determined not based on the specified offsets, unlike for non-replaced elements, but by the contents of the button itself. Since the used value of width is not auto, and the specified values of left and right are not auto, the values are over-constrained and the browser is forced to ignore right in order to respect width.
If you want the button to fill the entire height and width of the wrapper, don't use absolute positioning. Instead, specify 100% height and width on the button, and use padding on the wrapper to offset the button:
.wrapper {
height: 300px;
width: 300px;
background-color: #f33;
padding: 3px;
box-sizing: border-box;
}
.wrapper button {
height: 100%;
width: 100%;
}
<div class="wrapper">
<button>Hello world</button>
</div>
(If you can't use box-sizing, subtract the padding from the dimensions of the wrapper.)
The vertical alignment of the text probably has to do with how the browser draws button controls by default, which is usually based on system button controls.

You can use calc to get the exact width minus the padding you get from the positioning:
width: calc(100% - 6px);
JSFiddle

You might want to use inherit/100% value for width and height css properties.
.wrapper {
height: 300px;
width: 300px;
background-color: #f33;
padding: 3px;
}
.wrapper button {
width: inherit;
height: inherit;
}
Fiddle
NOTE: If you want to have the dimensions exactly 300 then subtract padding. (which will be 294px)

please use below css ..
.wrapper {
height: 300px;
width: 300px;
background-color: #f33;
position: relative;
padding: 3px
}
.wrapper button {
position: absolute;
top: 0;
bottom:0;
left:0;
right:0;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
width:100%;
}

I think you are trying to put button in center.You declared top and left 3px so no matter what you define bottom and right button is going to to be 3px from top and left ignoring other.To put button in center use marginFirst define width of button and set marginLike thia
.
wrapper button{
Width:100px;
margin:0px auto;
}
not margin doesn't work with absolute position.

.wrapper {
height: 300px;
width: 300px;
background-color: #f33;
position: relative;
}
.wrapper button {
position: absolute;
top: 3px;
bottom: 3px;width:97.5%;
right: 3px;
}
Try this.

You need to set the width of the button, to make it fill the space.
The easiest way to do this is to set it to the correct size.
.wrapper {
height: 300px;
width: 300px;
background-color: #f33;
position: relative;
}
.wrapper button {
position: absolute;
top: 3px;
bottom: 3px;
left: 3px;
right: 3px;
height: 294px;
width: 294px;
}

Related

absolute div inside absolute div cuts off with respect to relative position

I have 3 divs on top of each other having following css.
.d1 {
position: relative;
background-color: yellow;
height: 50px;
width: 100px;
overflow: hidden;
}
.d2 {
position: absolute;
background-color: green;
height: 25px;
width: 50px;
}
.d3 {
position: absolute;
left: 83px;
}
and the divs that have classes are as follows:
<div class="d1">
<div class="d2">
<div class="d3">text</div>
</div>
</div>
and as a result I see content of d3 cut off because of overflow:hidden in d1.
How can I avoid cut off content of d3 without modifying d1?
Getting around the overflow..
An element can overflow from a relative or absolute positioned parent by setting its position to fixed. An element that has position: fixed will have the default left,right,top, and bottom styles set as auto. This will position .d3 to the top-left of .d2, and then the left: 83px style will push it to the left from there.
Making up the additional space..
However, to get that additional movement to the right as the original markup, you will need to add margin-left: 8px, which will make-up the additional ~8px needed to replicate the original. Further adjustments to the position of .d3 will need to be done by setting the margin style (see below).
Your updated code should look like this..
.d1 {
position: relative;
background-color: yellow;
height: 50px;
width: 100px;
overflow: hidden;
}
.d2 {
position: absolute;
background-color: green;
height: 25px;
width: 50px;
}
.d3 {
position: fixed;
margin-left: 8px;
left: 83px;
}
Some considerations and caveats..
As a previous commenter mentioned, best practice would be to fix your html markup because this solution could cause issues if you ever need to move the position of .d3. For example, setting left,right,top, or bottom will cause the default setting of this style, auto, from being unset, and the element will be positioned relative to the viewport rather than the parent relative or absolute element.

Position an HTML element by center

What's the proper way to position an HTML element according to a center handle?
In this example:
XXXXXXXXX
|
|
123px
Assume the element should be position at absolute position left: 123px; but the text should be centered at that point, not start at it. The element text is dynamic, so I have no way of setting a static negative margin-left on it.
Is there a pure CSS way to achieve this? The JS way of measuring offsetWidth and then setting left after calculating width / 2 won't neccesarily work in my case due to various limitations.
One posibility is to set a transform translateX -50%
p {
position: relative;
display: inline-block;
left: 100px;
transform: translateX(-50%);
}
<p>ONE</p>
<br>
<p>TWO, LONGER</p>
<br>
<p>THREE, the longest</p>
It's fairly easy to achieve that and there are several ways to do it. Since you didn't post any HTML construct for your example, I'll just make up some.
The trick is to have an inline-block parent element which has the desired offset (123px) and inside that element you'll have another inline-block element with a left margin of -50%. Position both relative and you'll have the effect you are looking for.
#container {
position: relative;
}
#line {
width: 100px;
height: 100px;
left: 123px;
position: absolute;
border-left: 1px solid red;
}
#text {
left: 123px;
top: 50px;
display: inline-block;
position: relative;
}
#text p {
position: relative;
background: green;
margin-left: -50%;
display: inline-block;
color: #fff;
text-align: center;
padding: 10px;
box-sizing: border-box;
}
<div id="container">
<div id="line">
<-- 123px
</div>
<div id="text">
<p>
This is some dynamic text<br>the div has no absolute set width.
</p>
</div></div>
There are other ways as mentioned, probably depends on your general layout/HTML structure. I would definitely take a look at the flex-box properties, this might also be suitable here.
If you want to play around with it, here's a fiddle.
Some of various ways to do this with css:
If your element is a block:
.element{
width: 200px; /* Full width */
left: 50%;
margin-left: -100px; /* Half width */
position: absolute;
display: block;
}
or, if you're using css3:
.element{
width: 200px; /* Full width */
left: calc(50% - 100px);
position: absolute;
display: block;
}
You can also have a non-absolute approach, but the parent element position should be relative:
.element-parent{
position: relative;
}
.element-parent .element{
margin: 0 auto;
}
If you use text-oriented element (inline-block), this works with IE 7+:
.element-parent{
text-align: center;
}
.element-parent .element{
display: inline-block;
}

"top" CSS property has no effect when using a percentage

I have this CSS defined with my page:
.content {
background-image: url("img/bg.jpg");
width: 100%;
}
.exhibit {
width: 100%;
height: 100%;
text-align: center;
}
.yt-embed {
width: 560px;
height: 315px;
position: relative;
top: 50%;
}
The DIV with .yt-embed is inside one with .exhibit, and the DIV with .exhibit is inside one with .content.
My issue is that the "top" property in my .yt-embed class is having absolutely no effect. However, it does work when it is set to a pixel value, instead of a percentage.
Percentage values are relative-to-parent.
So, for any dimension of a given element, if you want to use a percentage value, the rendering engine must already know an explicit value for the corresponding dimension of the element's parent.
The one exception is the <html> element, which can accept a percentage value because the rendering engine will regard that value as relative-to-viewport instead of relative-to-parent.
Consequently, to enable your
.yt-embed {
top: 50%;
}
declaration to work, you'll need to declare:
html, body, div {
height: 100%;
}
at the start of your CSS.
My issue is that the "top" property in my .yt-embed class is having absolutely no effect.
Your problem is that your outter elements don't have a specific height. They are being expaded by the inner element .yt-embed that has the height declaration.
Using percentage based values is widely used and works fine. Here's a quick example:
* {
box-sizing: border-box;
}
.wrapper {
display: inline-block;
width: 300px;
height: 300px;
position: relative;
background: #f00;
padding: 10px;
}
.full.sized {
width: 100%;
height: 100%;
background: #0f0;
}
.inner {
position: absolute;
top: 50%;
left: 50%;
background: #00f;
color: #fff;
padding: 10px;
}
<div class="wrapper">
<div class="full sized">
<div class="inner">inner</div>
</div>
</div>
You can use the percents by changing the position to absolute
.yt-embed {
width: 560px;
height: 315px;
position: absolute;
top: 50%;
}
The parent element (in this case .exhibit) needs to have a pixel value on the height property, so that the browser can determine where exactly its position is.
You can read about top here: http://www.w3schools.com/cssref/pr_pos_top.asp
The same applies when applying a percentage value to the height of an element within another element; if the child has a percentage value then the parent must have a pixel value to have any effect.
Edit
Example:
.exhibit {
height: 315px;
*or*
min-height: 315px;
}
or create another div inside .exhibit, containing .yt-embed, with these values if necessary.
.yt-embed {
top: 50%;
position: absolute/relative;
width: 560px;
}

div-Block height depends from content inside

everyone!
I got a problem with changing height of block when form height inside it becomes more(maybe it's only looks like so,don't know).
My sample on http://jsfiddle.net/vXNCD
Maybe I have this problem, because I gave position for form using
position: relative;
left: 13em;
top: 9em;
If it's so, how to make positioning correctly?
How make my #content covering all inputs ??
If you want to position your form a little offside, use padding in the parent element instead of position relative.
Here is the fiddle: http://jsfiddle.net/vXNCD/13/
What i did was remove position relative and add padding to #content div plus added box-sizing to make sure padding is counted as a part of width.
#content
{
width: 70%;
min-height: 30em;
background-color: rgba(62,96,111,0.9);
position: relative;
margin: 5em auto;
-webkit-border-radius: 0.42em;
-moz-border-radius: 0.42em;
-o-border-radius: 0.42em;
-ms-border-radius: 0.42em;
border-radius: 0.42em;
padding: 9em 13em;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
You should add a padding-bottom: 9em to #content > form. The value should be equal to or greater than top: 9em. In this way your form will stay inside the block. See this jsfiddle.
#content > form
{
position: relative;
left: 13em;
top: 9em;
padding-bottom: 9em;
}
Or better, you should use padding-top: 9em instead of top: 9em so you avoid this problem altogether. See this jsfiddle.
#content > form
{
position: relative;
left: 13em;
padding-top: 9em;
}
Your element is positioned relative. Use padding to position the contents instead of top and left.
#content > form {
position: relative;
padding: 40px 60px;
}
If all you want is to get the form within the box, I don't see why you should use relative positioning at all. Just removing it, you will be fine. Then you can center the content (if you wish) with margin : 0 auto; where it's needed.
http://jsfiddle.net/9jNZG/
#content
{
width: 70%;
min-height: 30em;
background-color: rgba(62,96,111,0.9);
margin: 5em auto;
padding:1em;
}
Just added some padding to make it look a little better with some breathing room :), and of course. Removed the relative positioning.
Just remove the following styles,
content > form
{
position: relative;
left: 13em;
top: 9em;
}
What you are doing here is adjusting the form with respect(RELATIVE) to the #content,Then changing the left and top positions.
By default,the position of an element is static..Thus the #content will cover all the form data.

Input in div container, won't stretch

I have a div containing an input. I want the input to stretch to fill the available space, this works in Chrome but not IE and Firefox.
<div class="outer">
<input type="text" />
</div>
.outer{
width: 100%;
height: 40px;
position: relative;
}
input{
position: absolute;
top: 7px;
bottom: 7px;
left: 7px;
right: 7px;
}
JSFiddle: http://jsfiddle.net/wwMZg/1/
In Chrome it appears like this:
In Firefox and IE it appears like this:
In my real-use scenario there are other divs that contain images for corners, that's why the top, left, right, bottom values are set to 7px in this example.
I would like to avoid setting the width directly on the input, I wan't to set it on .outer.
Most input elements have padding/borders on them. You need to use the box-sizing property to adjust how the element dimensions are calculated.
http://jsfiddle.net/wwMZg/5/
.outer {
width: 100%;
height: 40px;
}
.outer input {
width: 100%;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
http://caniuse.com/#search=box-sizing
If you cant use box-sizing because you need to support older browsers, and don't mind adding another element to the markup, you can use an intermediate div
CSS
.outer{
width: 100%;
height: 40px;
position: relative;
}
.inner {
position: absolute;
top: 7px;
bottom: 7px;
left: 7px;
right: 7px;
}
input{
width: 100%;
}
HTML
<div class="outer">
<div class="inner">
<input type="text" />
</div>
</div>
Fiddle: http://jsfiddle.net/2mFgR/
Controlling the stretching and height of an input element
This styling problem is a bit intriguing since the input element seems to have its own set of rules.
Consider the following HTML:
<div class="outer">
<div class="inner">
<input type="text" />
</div>
</div>
and the CSS:
.outer {
width: 100%;
font-size: 20px;
background-color: green;
overflow: auto;
}
.inner {
margin: 7px;
}
input {
font-size: inherit;
width: 100%;
border: none;
}
Wrapping the input field in the .inner element allows it to expand to 100% without triggering horizontal overflow on the top level container.
However, the margins will not be fully symmetric unless you set border: none on the input field. This could be fixed using box-sizing to deal with the width of the borders.
With respect to the height property, input behaves like a regular inline, non-replaced element, that is, the height value does not apply and you need to use the font-size to get some control over the height.
See demo at jsFiddle
add width:100% to your input style
.outer{
width:100%;
height: 40px;
position:absolute;
}
input{
position:relative;
top: 7px;
bottom: 7px;
width:100%;
padding:0px;
margin-left:-1px;
border:1px solid gray;
}
It's the border that's offsetting it in IE