MollyPages.org
"You were wrong case. To live here is to live." |
Pages /
Database /
Forms /
Servlet /
Javadocs
/
License & Download /
Tutorials /
Cookbook
/
Contact & Hire
|
*, *:before, *:after { box-sizing: border-box; }For all examples,
border-box
is used and everything is HTML5 doctype;
#float { //no width specified float: left; border: 1px solid green; }
The float maximizes its width (for both text and img)...this should not happen, it should always shrink wrap.
#float { width: auto; float: left; border: 5px solid green; }
The float correctly shrink wraps to its content width.
As an aside, there is some spacing below the image. This is because it is aligned to baseline, so to fix it, we can say (something like) [not shown in example]:
img { padding:0; margin:0; vertical-align: middle; }
#float { width: 25% float: left; margin-right: 1%; border: 5px solid green; }
Experiment to move towards a flexible, N column layout (in this example, N=2).
Given a width of 25%, added a margin-right of 1% in the hopes of 1% margin for all content next to the float. But this doesn't work since the float margin only applies to the content next to the float, not the content the wraps below the float.
Also note, the float is position dependent. The image float was defined in the middle so text flows above it.
#left-float { width: 25% float: left; border: 5px solid green; } #right { margin-left: 26%; border: 5px solid yellow; }
This is a flexible, N column layout (in this example, N=2).
overflow: hidden or scroll
and then the design is full responsive.
The left side float has a contained image that escapes the float (overflows) when the window is shrunk. We fix this via overflow: hidden or scroll and then the design is full responsive.
We can also add a media query to not float if the window is smaller than say 320px, but stack the 2 sections instead.
#left-float { width: 25%; float: left; border: 5px solid green; overflow: hidden; } #right { border: 5px solid yellow; margin-left: 26%; } @media only screen and (max-width: 320px) { #float-left { float: none; width: 100%; } #right { margin-left: auto; } }
left + right width <= 100%
.
This approach is more flexible because it scales to N columns more easily (else each column would have to give progressively larger left margins, which we would have to calculate via summing up widths of all the other leftwards columns..no big deal but slighly more hassle that way).
#left-float { width: 25% float: left; border: 5px solid green; } #right-float {margin-left: 26%;border: 5px solid yellow; float: left; width: 75%; }
#left-float { width: 25% float: left; border: 5px solid green; } #right-float { margin-left: 26%; border: 5px solid yellow; float: right; width: 75%; }
<div style="clear:both"> -or- <br clear=both>One can also say:
#container { overflow: auto; } #footer { background: blue; border: 1px solid azure; }In this example, I've put both floats in a
#container
div with the above style. I've also added a footer div which will show up in the cleared section (The footer is outside the #container).
Further reading:
Further reading:
#container { padding: 20px; margin: 20px; border: 5px solid yellow; position: relative; } #absolute { width: 50%; position: absolute; top: 0; left: 0; border: 5px solid green; background: white; }
So, margins (of the parent container) are respected but padding is not respected. The absolute element touches the border of the parent.
This is actually as per spec
This only works when the absolute element has no borders. If it does have borders, then this method fails.
#container { padding: 20px; margin: 20px; border: 5px solid yellow; position: relative; } #absolute { width: 50%; position: absolute; top: 0; left: 0; border: 5px solid green; background: white; padding-left: inherit; padding-right: inherit; } #right { margin-left: 25%; border: 5px solid yellow; }
#left { position: absolute; top: 0; left: 0; border: 5px solid green; width: 25%; } #right { margin-left: 25%; border: 5px solid yellow; }
In this example, the absolute positioned block uses the body (since it is the closest ancestor) and
goes out of flow. The #right
block still has the padding of the body and is slightly
lower.
We can fix this by either giving body a 0 padding, or creating a parent container div (with relative positioning) and giving that a 0 padding. This example is shown below.
#left { position: absolute; top: 0; left: 0; border: 5px solid green; width: 25%; } #right { margin-left: 25%; border: 5px solid yellow; } #container { padding: 0; position: relative; }
#right
div does not have a left margin but
a size and is stuck to the right.
#left { position: absolute; top: 0; left: 0; border: 5px solid green; width: 25%; } #right { position: absolute; top: 0; right: 0; width: 75%; border: 5px solid yellow; } #container { padding: 0; position: relative; }
Responsive note: same as 2 floating %-tage divs. overflow should be set appropriately for images and media queries should be used to stack div's instead for small screens.
margin: 0 auto
#centered { position: absolute; left: 10px;; right: 10px; border: 5px solid green; } #container { position: relative; margin: 0 auto; width: 100%; padding: 0; border: 1px solid red; overflow: auto; //does not expand for absolute }
I've also used a parent container with a red border. The child div is centered in this container,
however, like floats, absolute elements are removed from the normal flow. So the height of the
parent is independent of the absolute div and only depends it's non-absolute content. (in this
example, I have a br in the parent which gives the parent #container
a 1-line height).
Unlike for floats, a overflow: auto
or br clear=both
doesn't work to
contain or get past the absolute div. We have to to give the parent container a height, which can
get tricky.
On a slighly different note: On designs with a header and then content below, I have seen absolute divs used for the content, with a top-margin equal to the height of a header div at the top. Not sure what the point of that is, since one can simply stack the 2 divs together and simply give the top header div a height.
inline-block
instead.
#left { display: inline-block; border: 5px solid green; } #right { display: inline-block; border: 5px solid yellow; }
inline-blocks
shrink fit it's contents but will expand to as much space as available before doing so. So, in this example, there is no width specified for either inline-block. Therefore the #left
one expands to as much is needs for the image and text, the #right
one does the same. Since there is whole lot more text in the right div, it takes up 100% of available space and the blocks end up being stacked on top of each other.
inline-block
instead.
#left { width: 25%; display: inline-block; border: 5px solid green; } #right { width: 75%; display: inline-block; border: 5px solid yellow; }
These blocks stack because the widths for each block add up to slightly more than 100%. There is
a space between inline-blocks, which is equal to a space character in whichever
font & size is currently in effect, ie:
foo| |bar
.
To fix this, see the next example.
left + space + right = 100%
and the amount needed for the space, depends on the
current font size/selection. So a little fragile.
#left { width: 25%; display: inline-block; border: 5px solid green; } #right { border: 5px solid yellow; display: inline-block; width: 75%; }//no space between the 2 divs in the HTML in this example:
Just like for floats, we have to set overflow: hidden|scroll|etc
to handle
content from one block (like contained iamges) from overflowing into another. (not shown
in this example).
Instead of futzing with spaces (and lack thereof) which is super fragile, we can designate a font size of zero on the outer level container and then reset the font size on each inner block level div. This again is still a bit hokey.
See: css-tricks article
vanseodesign article
Note: Inline blocks (when used for layout) are cleared via any non-inline block level element after the series of inline blocks.
#left { width: 25%; display: inline-block; border: 5px solid green; vertical-align: top; } #right { border: 5px solid yellow; display: inline-block; width: 75%; vertical-align: top; }//no space between the 2 divs in the HTML in this example:
This is nice but note, the left inline div has a different height than the right one. inline-blocks (like floats) have different heights. We can make the inline-blocks the same height (not shown here) by:
#left, #right { height: 400px; }
html
element.
)
body, html { height: 100%; } #left, #right { height: 50%; }
img { //this causes the image to grow very large width: 99%; //..so also add a max-width (can do this per image type) max-width: 200px; } div { overflow: hidden; }
Note, the image will shrink to very small (since there is no min-width on the image), so we should use a media query to stack the div's for small screens. We could add a min-width on the img of course, but then the image would overflow (and get cut off) on small screens.
table-cell
instead.
#left { width: 25%; display: table-cell; border: 5px solid green; } #right { border: 5px solid yellow; display: table-cell; width: 75%; }
This works great and is really the same as defining too td's inside a table (but not having to write the table tag itself).
Same as with inline-blocks, the blocks need to be vertically aligned.
#left { width: 25%; display: table-cell; vertical-align: top; border: 5px solid green; } #right { border: 5px solid yellow; display: table-cell; vertical-align: top; width: 75%; }
This also automatically solves the different height problems between the various floated and/or inline-blocks.
Finally, a great and easy way to lay out multiple columns...i.e., regressing back to the good old tables from 1997. Oh yeah!
Responsive note: Since these are table cells and have a percentage, the table will scroll of the right side of the page (and we will see a page scrollbar). Table cells never shrink their content, if the content is greater than the page width, the cells total up to become greater than the page width.
#left { width: 25%; display: table-cell; vertical-align: top; border: 5px solid green; } #right { border: 5px solid yellow; display: table-cell; vertical-align: top; width: 75%; } img { width: 99%; max-width: 200px; //can specify max-width different for different //image classes and id's }
This is similar to the inline-block case, where we also specified image sizes as a percentage of the parent container (div in that case, table-cell in this).
So, now the table does not scroll of the page (unless past a single word boundary, of
course), since the image will shrink. However, this shrinkage (heh) continues to a very
small size (since there is no min-width on the image). We should definitely use a media
query to stack the div's for small screens. We could add a min-width
on the
img of course, but then the table would overflow the page on small screens.
#fixed { position: fixed; top: 0; border: 5px solid green; background: white; }
In this case, the initial content of the main content div disappears below the fixed div.
#fixed { position: fixed; top: 0; height: 100px; border: 5px solid green; background: white; } #main { margin-top: 110px; }
We give a top margin for the #main
div, which can be fully seen if the user scrolls to
the top.
#fixed { position: fixed; left: 0; width: 100px; border: 5px solid green; background: white; } } #main { margin-left: 110px; }
We give a left margin for the #main
div and affix the fixed div to the left. This is an alternate to floating the div to the left.
#fixed { position: fixed; left: 0; width: 25% min-width: 100px; border: 5px solid green; background: white; } } #main { margin-left: 26% }
Responsive: Just of kicks, I've also added a min-width for the fixed div. However, below a certain width, the main content div goes under the fixed header because it's margin is less than the 100px the fixed width minimum size. We could take out the min-width of the fixed width div of course and set its contents to overflow: hidden
and/or use media queries to stack the divs below a certain size.
#height { height: 50%; border: 5px solid green; background: white; }
The height of the container is 600px but as I expand the window, the height is clearly less than 50%. The percentage of the element is a percentage of the parent and if the height of the parent is auto (the default), then a percentage of (whatever the auto lay out actually resulted in) is not calculated. Which is weird...analogous to widths, the height of the top most element should be the viewport height and percentages of children should then be based on that automatically. But the html element is not 100% high be default! (I don't think).
body { height: 100%; } #height { height: 50%; border: 5px solid green; background: white; }
That didn't work either.
html, body { height: 100%; } #height { height: 50%; border: 5px solid green; background: white; }
And that finally worked! The height is always 50%. Of course, we now have to worry about overflow if the content can't fit in 50%.
However, a vertical scroll bar shows up in the document window...Why ? Our div is only 50% of the 100% height, so why a scrollbar ? Answer: because of the margin/padding on the parent! So, in this case, if we say:
html, body { margin: 0; }then the scrollbar's disappear.
Note: 100% html height is the viewport (window size) height, not the height of the document box that is used for all the content (for multipage content). So a 1 page tall browser window, with 2 pages of content (and hence scrolling) inside a container with 100% height, would be container that is 1 page tall only (not 2 pages tall). The contents may overflow or scroll depending on how overflow is set.
html, body { height: 100%; margin: 0; } #height { height: 50%; border: 5px solid green; background: white; }
body
or html
#height { height: 250px; border: 5px solid green; background: white; }
And that also works, the height is always 250px. This is true even if the parent container is less than 250px..in that case we have the usual overflow handling.
#height { position: absolute; top: 0; height: 50%; border: 5px solid green; background: white; }
This has the same issue as regularly positioned elements, ie height doesn't work as percentage if ancestors have no height.
html, body { height: 100%; } #height { position: absolute; top: 0; height: 50%; border: 5px solid green; background: white; }
html, body { height: 100%; margin: 0; } #height { position: absolute; top: 0; height: 50%; border: 5px solid green; background: white; }
height
vs. min-height
?
#height1 { width: 50%; position: absolute; top: 0; left: 0; border: 5px solid green; background: yellow; height: 100%; overflow: auto; } #height2 { width: 50%; position: absolute; top: 0; right: 0; border: 5px solid green; background: pink; min-height: 100%; } The document also contains a bunch of content like so: START xxx.....xxx END
The height of an element is whatever height is needed to display all it's contents. If no height is set, the height is the natural height. min-height is only necessary to boost the minimum size of the element to greater than it's natural/content size.
Suppose the body is set to to 100% height, of html, which is also 100%, so the height of children is 100% of current viewport. As the window is resizes, the height will always be dynamically adjusted to tbe 100% of whatever the current size is.
Setting the height to 100% (percentage) of the body will have the same effect as setting the min-height to be 100%...if the content is less than 100% (ie fits in the current window). If the content is greater than what would fit in the window, then min-height doesn't do anything, since the height will be the natural height (ie needed to show all the content).
Basically, min-height when natural height is greater than min-height is useless.
#absolute { position: absolute; top: 10px; left: 10px; right: 10px; bottom: 10px; border: 5px solid green; background: white; }
#container { opacity: 0.5; padding: 30px; border: 5px solid yellow; } #child { border: 5px solid green; background: white; opacity: 1; }
The child opacity is 1 * parent_opacity = 0.5 opacity (relative to grandparent). opacity is a relative multiplier to the ancestor opacity, not an absolute. How do we make it absolute ?
#container { opacity: 0.5; padding: 30px; border: 5px solid yellow; } #container2 { background: white; padding: 30px; border: 5px solid red; opacity: 1; } #child { border: 5px solid green; background: white; opacity: 1; }
rgba
as the background of the element we want to make transparent.
#container { padding: 30px; border: 5px solid yellow; background: rgba(100%,100%,100%,0.5); } #child { border: 5px solid green; background: white; }
solved !
inline-block
).
top/botton margin have no effect (including negative margins) but left/right margins work.
left/right padding has an effect, but padding (and hence) borders has an effect on top/bottom as well!
#inline { border: 5px solid yellow; height: 100px; width: 100px; margin: 50px; } #inline2 { border: 5px solid green; height: 100px; width: 100px; padding: 50px; } #inline3 { border: 5px solid red; margin-top: -50px }
inline-block
elements, padding and margin cause lines above and below to move.
(negative margins don't have an effect).
#inline { border: 5px solid yellow; height: 100px; width: 100px; margin: 50px; display: inline-block; } #inline2 { border: 5px solid green; height: 100px; width: 100px; padding: 50px; display: inline-block; } #inline3 { border: 5px solid red; margin-top: -50px display: inline-block; }
text-align:center
aligns non-block elements to the center. Elements outside flow (like float) are of course not aligned at all, since the float takes precedence.
block elements are not aligned with this property. This can be easily seen when the block element is less than 100% width (like the yellow container2 in this example). To align block elements, use the left/margin auto trick.
However, inline-block elements (like images) are aligned but in the context of the entire text line they happen to be inside of (ie the whole line is aligned). So, the first 'is this centered' image is the only thing on that line so is centered. The line below has other text and the image and the text is aligned/centered as a whole.
body { text-align: center; padding: 30px; } #float { float: right; border: 5px solid red; width: 5em; } #container1 { border: 5px solid green; } #container2 { border: 5px solid yellow; width: 50%; } #container3 { border: 5px solid blue; width: 50%; margin: 0 auto; }
center
tag aligns everything (including block elements) in the center (minus floats of course since they aren't in flow).
body { padding: 30px; } #float { float: right; border: 5px solid red; width: 5em; } #container1 { border: 5px solid green; } #container2 { border: 5px solid yellow; width: 50%; } #container3 { border: 5px solid blue; width: 50%; }
Finally! a great and easy way to center things...the good old center from 1995. Oh yeah!
Or, using css: assign the div to be centered a table-cell display and assign parent div a table
display. Note, both table-cell
and table
(on parent) need to be present.
Simpler to just use a damn table. In this example, also declared body/html to be 100% height, since need to center on page.
html { height: 100%; } body { padding: 30px; border: 1px solid red; height: 100%; display: table; } #container1 { border: 5px solid yellow; width: 50%; display: table-cell; vertical-align: middle; } #container2 { border: 5px solid yellow; width: 50%; display: table-cell; vertical-align: middle; }
Note:, #container1
ends up with a width of 100% and not the 50% we specified in the CSS.
Each item that has display: table cell
, renders the same way as a table cell.
The width of the parent display: table
is relevant. In this case, the parent (body) is 100% but if it was anohter container, say 80% width, then all the child table-cell
elements would fit in the parent table width (and the percentage of each table-cell would be divided using the parent width).
html { height: 100%; } body { padding: 0px; margin: 0; border: 1px solid red; height: 100%; } #container1 { position: relative; top: 50%; transform: translateY(-50%); border: 5px solid yellow; }
This is fragile, in that if the element to be centered has more content than can fit in the parent, it gets moved past the top border of the parent element.
.panel { border: 5px solid yellow; width: 522px; /* including border 128*4 + 5px on both sides) */ margin: 0 auto; background: rgba(100%,100%,100%,1); } .panel a { float: left; width: 128px; height: 128px; padding: 6px; text-decoration: none; outline: none; color: #3260c7; } .panel img { width: 100%; height: 100%; border-radius: 100%; }
vw is horizontal viewport width percentage.
#item { height: 50vh; border: 5px solid yellow; }
Essentially, good for font sizes that adjust to window size, as well as setting height without worrying about having a height on all the ancestor elements. (vh is independent of ancestor vh)
Further reading: excellent article @ bitsofco.de
#item { height: 50vh; border: 5px solid yellow; }
So the vh is always the viewport height and contents might overflow if they can't fit. Tried overflow: hide
and that did hide the overflow as expected (not shown here).
html, body { height: 100%; padding: 0; margin: 0; } #item { height: 50vh; border: 5px solid yellow; min-height: 100%; }
Can get a little complex. If height (after 50vh is calculated) is greater than min-height, then height wins, which could be less than the natural height (in no height was specified).
body { /* to prevent horiz. scrollbar with 100% vw */ padding: 0; margin: 0; } #item { width: 50vw; border: 5px solid yellow; } #item2 { width: 100vw; border: 5px solid green; }
-moz-
and -webkit-
or this didn't work. (styles show without prefixes for brevity)
#item { column-count: 2; column-gap: 15px; column-rule: 5px solid yellow; } #item2 { column-count: 3; column-width: 50px; column-gap: 15px; column-rule: 5px dashed green; }
The column width doesn't seem to have any effect, columns seem to be distributed evenly across the entire width of the container.
Further reading: css tricks
3 divs, no z-index, stacked in lexical order.
The red div is first and has a pink child div
Then the yellow div
Then the green div
#a { position: absolute; background: red; top: 0; left: 0; } #a_1 { background: pink; } #b { position: absolute; background: yellow; top: 20px; left: 20px; } #c { position: absolute; background: green; top: 40px; left: 40px; }
Change the lexical order between red (now last) and green (now first) divs and see what happens.
/* now last lexically */ #a { position: absolute; background: red; top: 0; left: 0; } #a_1 { background: pink; } #b { position: absolute; background: yellow; top: 20px; left: 20px; } /* now first lexically */ #c { position: absolute; background: green; top: 40px; left: 40px; }
This reverses red and green, ie follows lexical order exactly.
Back to lexical order of red, yellow, green but give red a negative z-index. (and no z-index of yellow or green)
/* now last lexically */ #a { position: absolute; background: red; top: 0; left: 0; z-index: -10; } #a_1 { background: pink; } #b { position: absolute; background: yellow; top: 20px; left: 20px; } /* now first lexically */ #c { position: absolute; background: green; top: 40px; left: 40px; }
Same as lexical order, since z-index
of first element in lexical order is also the lowest and negative.
#a { position: absolute; background: red; top: 0; left: 0; z-index: 10; } #a_1 { background: pink; } #b { position: absolute; background: yellow; top: 20px; left: 20px; } #c { position: absolute; background: green; top: 40px; left: 40px; }
This swaps red and green, as if red had been declared last. So positive z-order is top-most. (Also, a z-order of 0 does nothing and maintains lexical order [now shown])
#a { position: absolute; background: red; top: 0; left: 0; z-index: 10; } #a_1 { background: pink; } #b { position: absolute; background: yellow; top: 20px; left: 20px; } /* now first lexically */ #c { position: absolute; background: green; top: 40px; left: 40px; }
This swaps red and green, as if red had been declared last. So positive z-order is top-most. (Also, a z-order of 0 does nothing and maintains lexical order [now shown])
#a { position: absolute; background: red; top: 0; left: 0; z-index: -10; } #a_1 { background: pink; z-index: 30; } #b { position: absolute; background: yellow; top: 20px; left: 20px; } #c { position: absolute; background: green; top: 40px; left: 40px; z-index: -5; }
The green is above red (as expected, since it's z-index is higher, i.e., less negative). Yellow is at default zero so is above both red and green (even though it appears before green lexically).
Setting the child #a_1
z-order to 30 raises it to the top of/within the parent
(#a
) but can't exceed the parent's overall z-order setting, so #a_1
is
still below the green (-5)
#a { position: absolute; background: red; top: 0; left: 0; z-index: -10; } #a_1 { background: pink; z-index: 30; } #b { position: absolute; background: yellow; top: 20px; left: 20px; } #c { position: absolute; background: green; top: 40px; left: 40px; z-index: -5; } #regular { background: white; border: 5px solid black; }
The regular div appears above the divs with negative z-orders (red and green). Red happens to be hidden completely in this example since its height is smaller than the regular one and a little bit of the green is poking thru at the bottom since it's height greater than the white/regular div. The yellow appears above the regular one, even though it is before the regular one, lexically. So absolute positioned div's with 0 or no z-order appear above regular elements.
More reading: z-index contexts
Use a iframe for persistent code that saves state across several pages and/or embeddable sections from other websites.
To navigate:
in JS:top.[frameid].location.href = 'foo.html'
in HTML:<a href='foo.html' target=[framename]>
Popup window to play with:
So, I've seen people concurrently use min-height
and height
both be 100%, which is meaningless. A height (or width) of 100% is sufficient.
#container { border: 5px solid black; width: 50%; min-width: 600px; max-width: 300px; background: yellow; font: white; }
The following algorithm describes how the two properties influence the used value of the width property.
The upshot of this is, min-width (if greater than max-width) always wins. This applies to all elements, including tables (on which, in addition to good old width, min/max width can also be set via CSS).
Popup window to play with:
How are events propogated between various layers? All click events written to console.log
.
#container { border: 5px solid black; height: 100%; margin: 50px; background: pink; } #div1 { position: absolute; top: 0; left: 0; width: 70%; height: 70%; background: yellow; font: white; } #div1child { border: 5px solid pink; } #div2 { position: absolute; top: 0; left: 0; width: 30%; height: 30%; background: green; font: white; } #div3 { position: absolute; top: 0; right: 0; width: 20%; height: 20%; background: blue; background: white; border: 5px solid blue; } #div4 { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: red; font: white; z-index: -1; }
pointer-events:none
to elements above it.
pointer-events:none
on an element prevents mouse/click events on that element and all of it's children.
div { border: 1px solid yellow; display: inline-block; } #padding { padding-top: 8px; padding-bottom: 8px; } #lineheight { line-height: 2; }
basically, min-width
queries are default mobile design, and then add desktop sizes via
progressively larger min-width of desktop sizes. max-width
is default desktop design
and then add mobile design by progressively smaller max-width.
Good discussion: on stackoverflow
Also the selection color can be changed via the selection property.
.element { background-color: red; transition: background-color linear .8s; } .element:hover { background-color: pink; } ::selection { background: green; color: white;