I'm attempting to understand why in this codepen the two boxes aren't perfectly aligned.
https://codepen.io/mburke05/pen/BYXOGP
html
<div class="div_one">pixel</div>
<div class="div_two">percent</div>
css
.div_one {
border: solid red;
transform: translate(70px, 20%) ;
width: 140px;
height: 60px;
}
.div_two {
border: solid blue;
transform: translate(50%, 30%) ;
width: 140px;
height: 60px;
}
I thought I understood that, when using %'s rather than pixel or other values, that the % value was based on the height of the element itself rather than the % of the parent (which in this case would be the viewport.)
However, to achieve what I believe is alignment, I would need to set translate(48%, 30%) as the value. Why is this? Isn't 70 50% of 140, or is there more to it than I'm understanding.
As a follow-up, can anybody explain why this is the preferred way of centering an object vertically mathematically?
div {
box-sizing : border-box
}
By default in the CSS box model, the width and height you assign to an element is applied only to the element's content box. If the element has any border or padding, this is then added to the width and height to arrive at the size of the box that's rendered on the screen. This means that when you set width and height you have to adjust the value you give to allow for any border or padding that may be added.
Read More here
.div_one {
border: solid red;
width: 140px;
height: 60px;
}
.div_two {
border: solid blue;
width: 140px;
height: 60px;
}
remove CSS property "transform", Both Div will align perfectly and if you want to move the position of the box means use padding or margin and if you want to fix in box position then use Position property
Related
Can someone explain why my div with table-layout:fixed is changing the width of its parent element (body in this case) to make it 100% when it shouldn't be 100% since it's positioned?
body {
border: 2px solid red;
height: 100vh;
margin:0;
padding: 0;
position: absolute;
}
.c{
display: table;
width: 80%; /* Any percentage value different from 0 */
table-layout:fixed;
outline: 2px solid blue;
}
<div class="c">d</div>
As you can see above, adding table-layout:fixed forces the body to be full width AND the percentage width on the div will work relatively to the width of the body!
This is not the case with the below snippet, where the behavior is somehow logical and intuitive:
body {
border: 2px solid red;
height: 100vh;
margin:0;
padding: 0;
position: absolute;
}
.c{
display: table;
width: 80%;
/* table-layout:fixed; */
outline: 2px solid blue;
}
<div class="c">d</div>
How does table-layout:fixed affect the parent element, which is positioned in this case?
As a side note, using pixel values with width produces a logical result:
body {
border: 2px solid red;
height: 100vh;
margin:0;
padding: 0;
position: absolute;
}
.c{
display: table;
width: 200px;
table-layout:fixed;
outline: 2px solid blue;
}
<div class="c">d</div>
We can also have some overflow with that strange behavior:
body {
margin:0;
position:relative;
width:300px;
border-top:20px solid green;
}
.container {
border: 2px solid red;
height: 100vh;
position: absolute;
}
.c {
display: table;
width: 120%;
table-layout: fixed;
outline: 2px solid blue;
animation:change 2s linear infinite alternate;
}
#keyframes change {
from{width:1%;}
to {width:150%}
}
<div class="container">
<div class="c">d</div>
</div>
Looks like you're not the first to bring this up. You might be the second, though.
To be clear, this is a combination of two issues:
The width of an absolutely positioned element is shrink-to-fit. Somehow the shrink-to-fit width is being determined to be as wide as the absposed element's containing block will allow. (The containing block for the absolutely positioned body is the initial containing block.)
A percentage width on an element whose containing block depends on its contents for auto sizing results in undefined behavior.
Issue #2 is pretty easy to write off:
implementations agree not to calculate the width of either element more than once.
i.e. body is sized using shrink-to-fit, then the table is set to 80% of that width, and the size of body is "not computed again". The only "undefinedness" of this is that the spec doesn't require or disallow, or indeed care what implementations do.
So the question then boils down to why shrink-to-fit is yielding "as wide as possible" in #1 prior to determining the size of the table in #2. Here is how the spec describes shrink-to-fit for absposed elements:
[...] Roughly: calculate the preferred width by formatting the content without breaking lines other than where explicit line breaks occur, and also calculate the preferred minimum width, e.g., by trying all possible line breaks. CSS 2.1 does not define the exact algorithm. Thirdly, calculate the available width: this is found by solving for 'width' after setting 'left' (in case 1) or 'right' (in case 3) to 0.
Then the shrink-to-fit width is: min(max(preferred minimum width, available width), preferred width).
But this doesn't tell us why, or even that, the preferred width of a fixed-layout table is "as wide as its containing block will allow". Neither css-sizing-3 nor css-tables-3 appears to contain the answer.
According to David Baron (from the same thread), who works on Gecko:
Fixed-layout tables report an intrinsic max-content inline size as infinite.
(note that "max-content inline size" means the same thing as "preferred width")
So there's our answer. The unbounded max-content inline size of fixed-layout tables is what causes this table's absolutely positioned parent to be stretched as wide as its own containing block (the initial containing block) will allow, in contrast to auto-layout tables.
And, at least for now, this is as close as I'll get to an official source because I'm having trouble reaching the same conclusion just by reading css-sizing-3, and I'm unsure if David's statement is based on Gecko's behavior alone, behavior of all implementations, or on specified behavior.
This is my explanation based on the described above issue so it can be viewed as speculation based on the bounty requirements for "official resources".
When table-layout: fixed is applied, the content no longer dictates the layout, but instead, the browser uses any defined widths from the table's first row to define column widths. If no widths are present on the first row, the column widths are divided equally across the table, regardless of content inside the cells.
In order for a value of fixed to have any effect, the table's width has to be set to something other than auto (the default for the width property) ... source
Once table-layout:fixed; is applied without the parent container having any set width and its own width set in percents it would expand its parent container (whatever that container is body/div/etc) to 100% and take the specified width (in this case 80%) relative to that of the parent.
It would do this since its default purpose is with width being set to make sure its columns width is distributed evenly regardless if there are columns or not. If they aren't any columns it would treat the element as one column. To do that it would still need its width to be relative to its parent (when its own width is set in %).
Example table-layout:fixed is not applied since it has no defined width although it is set in the CSS, table-layout:auto is applied as that is the default:
body {
border: 2px solid red;
height: 100vh;
margin: 0;
padding: 0;
position: absolute;
}
.c {
display: table;
table-layout: fixed;
/* width: 80%; */
outline: 2px solid blue;
}
<div class="c">d</div>
Now let's set the width:
body {
border: 2px solid red;
height: 100vh;
margin: 0;
padding: 0;
position: absolute;
}
.c {
display: table;
table-layout: fixed;
width: 80%;
outline: 2px solid blue;
}
<div class="c">d</div>
In your second example,
body {
border : 2px solid red;
height : 100vh;
margin : 0;
padding : 0;
position : absolute;
}
.c {
display : table;
width : 80%;
outline : 2px solid blue;
/* table-layout : fixed; */
}
You have absolutely positioned the body, so it's taken out of normal flow and it doesn't influence the positioning or sizing of its .c child.
So the width of .c isn't 80% of the body as you might initially expect.
You can however use units like pixels or vw to set the width of .c and the result will be more intuitive, like this.
.c {
display : table;
width : 80vw;
outline : 2px solid blue;
/* width : 80%; */
/* table-layout : fixed; */
}
Similarly, when you use table-layout:fixed; your browser uses an algorithm to calculate the width of the table which is similar to using units like pixels or vw to calculate the width for the table.
To quote from the W3C spec
17.5.2.1 Fixed table layout With this (fast) algorithm, the horizontal layout of the table does not depend on the contents of the cells ...
This question already has answers here:
How to draw circle in html page?
(19 answers)
Closed 6 years ago.
In CSS it is allowed to write something like this.
#div-with-border {
width: 100%; // scales with parent wrapper
height: 30%; // scales with parent wrapper
border: 1px solid black;
border-radius: 10%;
}
If #div-width-border isn't a perfect square the border won't be a circle, since this means, that 10% of the width and 10% of the height are used for the border-radius (which differ). I would like to get perfect circles... I can't use px, since the border-radius depends on the height/width.
I'm sure that the width of #div-width-border is always greater than the height, of the element. I would need a border radius of the size 100% of element height to get a perfect circle, but just 100% won't do it, since it'll use the element width for one part of the radius calculation.
If you know the ratio between the width and the height, you may use the Slash-Annotation to specify different %-values for horizontal and vertical border-radius. An Example is below:
.wrapper {
width: 300px;
height: 300px;
margin: 0 auto;
}
.div-with-border {
width: 100%;
height: 25%;
background-color: blue;
border: 1px solid black;
border-radius: 10% / 40%;
}
<div class="wrapper">
<div class="div-with-border"></div>
</div>
Have you tried border-radius: 50%; ? Since you're saying that the div is a perfect square, setting border radius to 50% should work
I know this title is probably about the most common on SO, but I seem to have a very specific problem that I can't find documented.
I have a div that I want to be exactly square, so I followed the CSS advice in this answer. I also want a child div to fill this space, so I've followed all the standard guidelines of having a clear:both div in a wrapper, etc, but my child div is still not filling its parent. The problem is the height: 0 of the parent div - is there a solution to this but still maintaining the exact square (preferably pure CSS, I'm aware there are JS solutions). Example of this is at this fiddle.
You can give the inner box an absolute position and set it to conform to the edges of the containing box:
.box div {
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
border: 1px solid black;
display: block;
background-color: rgba(0,0,0,0.1);
}
jsfiddle
Not sure if it's any better to what you proposed, maybe if you wanted content in the box?
If you're not too worried about support then using vh, vw, or vmin would be a good alternative. Since height would actually be set you could easily set the child element to fill the parent.
CSS:
.parent {
width: 50vmin;
height: 50vmin;
background-color: blue;
margin: 0 auto;
}
.child {
width: 100%;
height: 100%;
background-color: red;
}
HTML:
<div class='parent'>
<div class='child'></div>
</div>
Here's an example. I like vmax, but it's not as well supported as vmin, vh, and vw.
This padding trick for responsive boxes work with absolute positioning.
css-padding-trick-responsive-intrinsic-ratios
So use absolute positioning for inner div.
.box {
...
position: relative;
}
.box div {
...
position: absolute;
left: 0;
top: 0;
}
Adding padding-bottom: 100% to the child div does fill the space and seems to be a fix; the updated jsfiddle reflects this
I have a container div (it has both width an height set in pixels).
Is there a way to add a child div that will fill its entire parent but still have margin and or padding ?
suppose the parent div is 200px wide, and 200px high.
if I give the child div a width/height of 100% then it assumes that I mean for the content are to be of size 200px and then if I add padding or margins the size of the child becomes bigger then that of the parent.
I want the child div's content area to be what ever is left after taking out 5px margins on each side...
and please don't tell me to subtract 2*5px from 200px - I know that but I am looking for a better solution.
could it be that css can't handle such a simple task...
You could try the following:
#outer {
width: 200px;
height: 200px;
background: blue;
position: relative;
}
.inner {
position: absolute;
top: 5px;
right: 5px;
bottom: 5px;
left: 5px;
}
demo: http://jsfiddle.net/wYNYh/1/
Set all elements to have box-sizing as border-box in your stylesheet.
This will sum up the padding of all elements so you don't have to worry about any disruptions if you add any padding.
*{
box-sizing: border-box;
}
Something like this: http://jsfiddle.net/Rnf82/ ?
You can set the padding of the outer div. Then the inner div will only occupy what's left.
Have a look at this: (try yourself at jsFiddle)
.outer {
width: 200px;
height: 200px;
background-color: #DD0000;
padding: 5px;
box-sizing: border-box;
}
.inner {
width: 100%;
height: 100%;
background-color: #0000DD;
}
<div class="outer">
<div class="inner"></div>
</div>
really these two ways of doing this is equivalent as far as the question is concerned. It is important to remember the redundancy generated by how html and css standards are setup.
See the box stuck the bottom right. Right now it as a fixed height of 300px. Instead I would like to be just as high as necessary. Meaning I need the height to adjust automatically to the content. When I remove the height property it assumes full height.
Additionally, I would like to be able to "refresh" the height whenever I update the content via javascript (jQuery).
Your seeing a height of 100% because your style for html, body, div, iframe specifies height of 100%. To override this, just set your height to "auto". Like this:
div.sidebar {
border-left: thin solid #66CCFF;
border-right: thin solid #66CCFF;
bottom: 0;
display: inline-block;
height: auto; /* <-- New Value */
/*height: 300px; <-- Old Value */
overflow: hidden;
position: absolute;
right: 40px;
width: 200px;
}
This will size the box so that it is only the same size as the content. You might also want to consider using the max-height property to set an upper limit though. Say something like max-height:640px;.
Change this properties:
div.sidebar {
position: fixed;
height: auto;
}
I think you won't need jquery to change height, just change content.
Change height: 300px; to height: auto;.