I am struggling to understand how CSS lays out elements on a page. This is a sketch of the layout I am trying to achieve:
And inside canvas-column-1
I want to add a canvas element i.e it will be a child of canvas-column-1
. However when I do this I find that this moves the position of canvas-column-2
which is sibling of canvas-column-1
so I anticipated it would not be affected by any child elements of its siblings:
CSS:
:root {
--header-height: 100px;
--footer-height: 20px;
--header-background: cornflowerblue;
--column-1-width: 200px;
}
.header {
height: var(--header-height);
min-height: var(--header-height);
max-height: var(--header-height);
background-color: var(--header-background);
}
.main-content {
min-height: calc(100vh - var(--header-height) - var(--footer-height));
max-height: calc(100vh - var(--header-height) - var(--footer-height));
min-width: 100vw;
max-width: 100vh;
width: 100vw;
position: absolute;
top: var(--header-height);
left: 0;
right: 0;
}
.footer {
min-height: var(--footer-height);
max-height: var(--footer-height);
background-color: var(--header-background);
position: absolute;
top: calc(100vh - var(--footer-height));
left: 0;
right: 0;
}
.column-1 {
min-width: var(--column-1-width);
max-width: var(--column-1-width);
width: var(--column-1-width);
min-height: calc(100vh - var(--header-height) - var(--footer-height));
max-height: calc(100vh - var(--header-height) - var(--footer-height));
background-color: indianred;
/* display: none; hidden and does NOT take up space. */
/* -OR USE- */
/* visibility: hidden; Hidden but still takes up space. */
display: inline-block;
position: absolute;
top: 0;
left: 0;
}
.column-2 {
min-width: calc(100vw - var(--column-1-width));
max-width: calc(100vw - var(--column-1-width));
width: calc(100vw - var(--column-1-width));
min-height: calc(100vh - var(--header-height) - var(--footer-height));
max-height: calc(100vh - var(--header-height) - var(--footer-height));
background-color: blueviolet;
display: inline-block;
position: absolute;
top: 0;
left: var(--column-1-width);
}
.canvas-column-1 {
display: inline-block;
min-width: 50%;
max-width: 50%;
width: 50%;
min-height: calc(100vh - var(--header-height) - var(--footer-height));
max-height: calc(100vh - var(--header-height) - var(--footer-height));
height: calc(100vh - var(--header-height) - var(--footer-height));
background-color: antiquewhite;
}
.canvas-column-2 {
display: inline-block;
min-width: 50%;
max-width: 50%;
width: 50%;
min-height: calc(100vh - var(--header-height) - var(--footer-height));
max-height: calc(100vh - var(--header-height) - var(--footer-height));
height: calc(100vh - var(--header-height) - var(--footer-height));
background-color: darkgray;
}
.left-canvas {
width: 200px;
height: 200px;
border: 4px dashed darkblue;
}
HTML
<div>
<div >This is the header</div>
<div >
<div ></div>
<div >
<div >Canvas Column 1
<canvas #leftCanvas height="200px" width="200px"></canvas>
</div>
<div >Canvas Column 2</div>
</div>
</div>
<div ></div>
</div>
I have used a lot of absolute
positioning in mainly because I found that when it came to absolute positioning of canvas-column-1
and canvas-column-2
they would be relative to they also needed a non-static parent element otherwise they would not be positioned or sized correctly. Please note this example is for my understanding of how CSS positions and lays out elements.
CodePudding user response:
I don't quit remember where i've read this in docs (i will look it up later), And I may not be remembering it correctly.
replaced elements dictates where the text line is in inline level layout, that is controlled with vertical-align
property, which by default it is set to baseline, if you would change vertical-align
on the appropriate element, it should fix it.
EDIT
The explanation
From the doc
A line box is always tall enough for all of the boxes it contains. However, it may be taller than the tallest box it contains (if, for example, boxes are aligned so that baselines line up). When the height of a box B is less than the height of the line box containing it, the vertical alignment of B within the line box is determined by the 'vertical-align' property.
Replaced elements don't actually dictates where the line is, But because they can be inline and sit next to text, and since they are generally taller than text that is why it pushed everything downward.
If you want you could decrease the height of the canvas and see the line moves upward.
There also a different issue with inline-block layout, which is that spaces and line breaks in the markup are not ignored, therefore manual calculations of available space won't work as expected.
You can read more about that How do I remove the space between inline/inline-block elements?
Here's a demo
Look at how .canvas-column-1
and .canvas-column-2
are not spaced out which fixes the issue with the column .canvas-column-2
not fitting on the same line.
:root {
--header-height: 100px;
--footer-height: 20px;
--header-background: cornflowerblue;
--column-1-width: 200px;
}
.header {
height: var(--header-height);
min-height: var(--header-height);
max-height: var(--header-height);
background-color: var(--header-background);
}
.main-content {
min-height: calc(100vh - var(--header-height) - var(--footer-height));
max-height: calc(100vh - var(--header-height) - var(--footer-height));
min-width: 100vw;
max-width: 100vh;
width: 100vw;
position: absolute;
top: var(--header-height);
left: 0;
right: 0;
}
.footer {
min-height: var(--footer-height);
max-height: var(--footer-height);
background-color: var(--header-background);
position: absolute;
top: calc(100vh - var(--footer-height));
left: 0;
right: 0;
}
.column-1 {
min-width: var(--column-1-width);
max-width: var(--column-1-width);
width: var(--column-1-width);
min-height: calc(100vh - var(--header-height) - var(--footer-height));
max-height: calc(100vh - var(--header-height) - var(--footer-height));
background-color: indianred;
/* display: none; hidden and does NOT take up space. */
/* -OR USE- */
/* visibility: hidden; Hidden but still takes up space. */
display: inline-block;
position: absolute;
top: 0;
left: 0;
}
.column-2 {
min-width: calc(100vw - var(--column-1-width));
max-width: calc(100vw - var(--column-1-width));
width: calc(100vw - var(--column-1-width));
min-height: calc(100vh - var(--header-height) - var(--footer-height));
max-height: calc(100vh - var(--header-height) - var(--footer-height));
background-color: blueviolet;
display: inline-block;
position: absolute;
top: 0;
left: var(--column-1-width);
}
.canvas-column-1 {
display: inline-block;
min-width: 50%;
max-width: 50%;
width: 50%;
min-height: calc(100vh - var(--header-height) - var(--footer-height));
max-height: calc(100vh - var(--header-height) - var(--footer-height));
height: calc(100vh - var(--header-height) - var(--footer-height));
background-color: antiquewhite;
}
.canvas-column-2 {
display: inline-block;
min-width: 50%;
max-width: 50%;
width: 50%;
min-height: calc(100vh - var(--header-height) - var(--footer-height));
max-height: calc(100vh - var(--header-height) - var(--footer-height));
height: calc(100vh - var(--header-height) - var(--footer-height));
background-color: darkgray;
}
.left-canvas {
width: 200px;
height: 200px;
border: 4px dashed darkblue;
}
/* Solution */
.canvas-column-2{
vertical-align:top;
}
<div>
<div >This is the header</div>
<div >
<div ></div>
<div >
<div >Canvas Column 1
<canvas #leftCanvas height="200px" width="200px"></canvas>
</div><div >Canvas Column 2</div>
</div>
</div>
<div ></div>
</div>