Related
I'm trying to find a way to create a custom highlight in CSS that takes up ~50% of the text height, centered vertically, that also works over multiple lines. I can do it a few ways that work on a single line, but all fall over when applied to multi line text, or aren't able to vertically center.
hr {
margin: 15px 0;
}
.title-psuedo .background {
position: relative;
padding-left: 40px;
padding-right: 40px;
}
.title-psuedo .background:after {
content: "";
position: absolute;
width: 100%;
background: yellow;
left: 0;
bottom: 0.3em;
height: 0.4em;
z-index: -1;
}
.title-mark mark {
display: inline-block;
line-height: 0em;
padding-bottom: 0.5em;
padding-left: 40px;
padding-right: 40px;
}
.title-shadow .background {
box-shadow: inset 0 -0.5em 0 yellow;
padding-left: 40px;
padding-right: 40px;
}
.title-background .background {
padding: 0 40px;
line-height: 0.5em;
margin: 0.25em 0;
background-color: yellow;
display: inline-block;
}
<div class="title title-psuedo">
<span class="background">This is the desired effect.</span>
</div>
<hr>
<div class="title title-psuedo">
<span class="background">This works on one line, but not when the text spans onto 2 separate lines, as the background messes up and only appears on the last line of the content.</span>
</div>
<hr>
<div class="title title-mark">
<mark>This works on one line, but not when the text spans onto 2 separate lines, as the lines merge into one single line which isn't legible. Also, I'm not sure the highlight can be centered vertically.</mark>
</div>
<hr>
<div class="title title-shadow">
<span class="background">This works on multiple lines, but I'm not sure the highlight can be centered vertically. Additionally, the second line does not have the same padding as the first.</span>
</div>
<hr>
<div class="title title-background">
<span class="background">This works on one line, but not when the text spans onto 2 separate lines as the line height collapses the text together and the highlight covers both lines without a gap. The second line does have the initial padding however.</span>
</div>
Use gradient and box-decoration-break
.title {
--lineHeight: 1.4em;
}
.title span {
line-height: var(--lineHeight);
padding: 0 40px;
background: linear-gradient(yellow 0 0) 0/100% calc(var(--lineHeight)/4) no-repeat;
box-decoration-break: clone;
-webkit-box-decoration-break: clone;
}
.title {
margin: 0 20px;
}
<div class="title title-psuedo">
<span class="background">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut eget mi vitae felis molestie volutpat. Integer viverra arcu id turpis molestie, id mollis enim molestie. Proin luctus auctor dictum. Maecenas nec libero bibendum, semper erat a, tristique nunc. Fusce accumsan feugiat ante,</span>
</div>
I found a solution with the help of repeating-linear-gradient() CSS property. In my solution you must define font-size and line-height. Then according to them you define the last number in repeating-linear-gradient(). Here is my code:
.text-deco .background2 {
line-height: 2;
font-size: 1rem;
display: block;
background-image: repeating-linear-gradient(transparent,transparent 0.9rem,yellow 0.9rem, yellow 1.1rem,transparent 1.1rem, transparent 2rem);
}
<div class="title text-deco">
<span class="background2">This works on one line, but not when the text spans onto 2 separate lines as the line height collapses the text together and the highlight covers both lines without a gap. The second nd the highlight covers both lines without a gap. The second</span>
</div>
I mean that for example If you want to have font-size:2rem and line-height:2 then you must change the last part (transparent 2rem) of repeating-linear-gradient() to transparent 4rem and then adjust other values in repeating-linear-gradient() according to that. For example 1.1 may change to 2.8. Maybe now my settings does not show the highlight in exact vertical position, but you can adjust values to reach your desired one.
I have floated images and inset boxes at the top of a container using float:right (or left) many times. Now, I need to float a div to the bottom right corner of another div with the normal text wrap that you get with float (text wrapped above and to the left only).
I thought this must be relatively easy even though float has no bottom value but I haven't been able to do it using a number of techniques and searching the web hasn't come up with anything other than using absolute positioning but this doesn't give the correct word wrap behaviour.
I had thought this would be a very common design but apparently it isn't. If nobody has a suggestion I'll have to break my text up into separate boxes and align the div manually but that is rather precarious and I'd hate to have to do it on every page that needs it.
Set the parent div to position: relative, then the inner div to...
position: absolute;
bottom: 0;
...and there you go :)
A way to make it work is the following:
Float your elements left like normal
Rotate the parent div 180 degrees using
-moz-transform:rotate(180deg);
-webkit-transform:rotate(180deg);
-o-transform:rotate(180deg);
-ms-transform:rotate(180deg);
filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);
JSfiddle: http://jsfiddle.net/wcneY/
Now rotate all the elements that float left (give them a class) 180 degrees to put them straight again. Voila! they float to the bottom.
After struggling with various techniques for a couple of days I have to say that this appears to be impossible. Even using javascript (which I don't want to do) it doesn't seem possible.
To clarify for those who may not have understood - this is what I am looking for: in publishing it is quite common to layout an inset (picture, table, figure, etc.) so that its bottom lines up with the bottom of the last line of text of a block (or page) with text flowing around the inset in a natural manner above and to the right or left depending on which side of the page the inset is on. In html/css it is trivial to use the float style to line up the top of an inset with the top of a block but to my surprise it appears impossible to line up the bottom of the text and inset despite it being a common layout task.
I guess I'll have to revisit the design goals for this item unless anyone has a last minute suggestion.
I have acheived this in JQuery by putting a zero width strut element above the float right, then sizing the strut (or pipe) according to parent height minus floated child's height.
Before js kicks in I am using the position absolute approach, which works but allows text flow behind. Therefore I switch to position static to enable the strut approach.
(header is the parent element, cutout is the one i want bottom right, and pipe is my strut)
$("header .pipe").each(function(){
$(this).next(".cutout").css("position","static");
$(this).height($(this).parent().height()-$(this).next(".cutout").height());
});
CSS
header{
position: relative;
}
header img.cutout{
float:right;
position:absolute;
bottom:0;
right:0;
clear:right
}
header .pipe{
width:0px;
float:right
}
The pipe must come 1st, then the cutout, then the text in the HTML order.
This puts a fixed div at the bottom of the page and fixes to the bottom as you scroll down
#div {
left: 0;
position: fixed;
text-align: center;
bottom: 0;
width: 100%;
}
Put the div in another div and set the parent div's style to position:relative; Then on the child div set the following CSS properties: position:absolute; bottom:0;
If you set the parent element as position:relative, you can set the child to the bottom setting position:absolute; and bottom:0;
#outer {
width:10em;
height:10em;
background-color:blue;
position:relative;
}
#inner {
position:absolute;
bottom:0;
background-color:white;
}
<div id="outer">
<div id="inner">
<h1>done</h1>
</div>
</div>
If you're okay with only the bottom-most line of the text going to the side of the block (as opposed to completely around and underneath it, which you can't do without ending the block and starting a new one), it's not impossible to float a block to one of the bottom corners of a parent block. If you put some content in a paragraph tag within a block and want to float a link to the bottom right corner of the block, put the link within the paragraph block and set it to float: right, then put in a div tag with clear: both set just underneath the end of the paragraph tag. The last div is to make sure the parent tag surrounds the floated tags.
<div class="article" style="display: block;">
<h3>title</h3>
<p>
text content
Read More
</p>
<div style="clear: both;"></div>
</div>
With the introduction of Flexbox, this has become quite easy without much hacking. align-self: flex-end on the child element will align it along the cross-axis.
.container {
display: flex;
}
.bottom {
align-self: flex-end;
}
<div class="container">
<div class="bottom">Bottom of the container</div>
</div>
Output:
.container {
display: flex;
/* Material design shadow */
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12);
height: 100px;
width: 175px;
padding: 10px;
background: #fff;
font-family: Roboto;
}
.bottom {
align-self: flex-end;
}
<div class="container">
<div class="bottom">Bottom of the container</div>
</div>
I had been find this solution for a long time as well.
This is what I get:
align-self: flex-end;
link: https://philipwalton.github.io/solved-by-flexbox/demos/vertical-centering/
However, I can't remember from where I opened this link. Hope it helps
If you want the text to wrap nicely:-
.outer {
display: table;
}
.inner {
height: 200px;
display: table-cell;
vertical-align: bottom;
}
/* Just for styling */
.inner {
background: #eee;
padding: 0 20px;
}
<!-- Need two parent elements -->
<div class="outer">
<div class="inner">
<h3>Sample Heading</h3>
<p>Sample Paragragh</p>
</div>
</div>
This is now possible with flex box.
Just set the 'display' of parent div as 'flex' and set the 'margin-top' property to 'auto'.
This does not distort any property of both the div.
.parent {
display: flex;
height: 100px;
border: solid 1px #0f0f0f;
}
.child {
margin-top: auto;
border: solid 1px #000;
width: 40px;
word-break: break-all;
}
<div class=" parent">
<div class="child">I am at the bottom!</div>
</div>
I know that this stuff is old, but I recently ran into this problem.
use absolute position divs advice is really silly, because the whole float thing kind of loses point with absolute positions..
now, I did not find an universal solution, but in a lot of cases prople use floating divs just to display something in a row, like a series of span elements. and you can't vertically align that.
to achieve a similar effect you can do this: do not make the div float, but set it's display property to inline-block. then you can align it vertically however it pleases you. you just need to set parent's div property vertical-align to either top, bottom, middle or baseline
i hope that helps someone
One interesting approach is to stack a couple of right float elements on top of each other.
<div>
<div style="float:right;height:200px;"></div>
<div style="float:right;clear:right;">Floated content</div>
<p>Other content</p>
</div>
Only problem is that this only works when you know the height of the box.
I would just do a table.
<div class="elastic">
<div class="elastic_col valign-bottom">
bottom-aligned content.
</div>
</div>
And the CSS:
.elastic {
display: table;
}
.elastic_col {
display: table-cell;
}
.valign-bottom {
vertical-align: bottom;
}
See it in action:
http://jsfiddle.net/mLphM/1/
I tried several of these techniques, and the following worked for me, so if all else here if all else fails then try this because it worked for me :).
<style>
#footer {
height:30px;
margin: 0;
clear: both;
width:100%;
position: relative;
bottom:-10;
}
</style>
<div id="footer" >Sportkin - the registry for sport</div>
A chose this approach of #dave-kok. But it works only if the whole content suits without scrolling. I appreciate if somebody will improve
outer {
position: absolute;
bottom: 0;
width: 100%;
height: 100%;
}
.space {
float: right;
height: 75%;
}
.floateable {
width: 40%;
height: 25%;
float: right;
clear: right;
}
Here is code http://jsfiddle.net/d9t9joh2/
Not sure, but a scenario posted earlier seemed to work if you use position: relative instead of absolute on the child div.
#parent {
width: 780px;
height: 250px;
background: yellow;
border: solid 2px red;
}
#child {
position: relative;
height: 50px;
width: 780px;
top: 100%;
margin-top: -50px;
background: blue;
border: solid 2px green;
}
<div id="parent">
This has some text in it.
<div id="child">
This is just some text to show at the bottom of the page
</div>
</div>
And no tables...!
To use css margin-top property with purpose to set footer to the bottom of its container. And to use css text-align-last property to set the footer contents at center.
<div class="container" style="margin-top: 700px; text-align-last: center; ">
<p>My footer Here</p>
</div>
A combination of floating and absolute positioning does the work for me. I was attempting to place the send time of a message at the bottom-right corner of the speech bubble. The time should never overlap the message body and it will not inflate the bubble unless it's really necessary.
The solution works like this:
there're two spans with identical text;
one is floated but invisible;
the other is absolutely positioned to the corner;
The purpose of the invisible floated one is to ensure space for the visible one.
.speech-bubble {
font-size: 16px;
max-width: 240px;
margin: 10px;
display: inline-block;
background-color: #ccc;
border-radius: 5px;
padding: 5px;
position: relative;
}
.inline-time {
float: right;
padding-left: 10px;
color: red;
}
.giant-text {
font-size: 36px;
}
.tremendous-giant-text {
font-size: 72px;
}
.absolute-time {
position: absolute;
color: green;
right: 5px;
bottom: 5px;
}
.hidden {
visibility: hidden;
}
<ul>
<li>
<span class='speech-bubble'>
This text is supposed to wrap the time <span> which always seats at the corner of this bubble.
<span class='inline-time'>13:55</span>
</span>
</li>
<li>
<span class='speech-bubble'>
Absolute positioning doesn't work because it doesn't care if the two pieces of text overlap. We want to float.
<span class='inline-time'>13:55</span>
</span>
</li>
<li>
<span class='speech-bubble'>
Easy, uh?
<span class='inline-time'>13:55</span>
</span>
</li>
<li>
<span class='speech-bubble'>
Well, not <span class='giant-text'>THAT</span>
easy
<span class='inline-time'>13:56</span>
</span>
</li>
<li>
<span class='speech-bubble'>
<span class='tremendous-giant-text'>See?</span>
<span class='inline-time'>13:56</span>
</span>
</li>
<li>
<span class='speech-bubble'>
The problem is, we can't tell the span to float to right AND bottom...
<span class='inline-time'>13:56</span>
</span>
</li>
<li>
<span class='speech-bubble'>
We can combinate float and absolute: use floated span to reserve space (the bubble will be inflated if necessary) so that the absoluted span is safe to go.
<span class='inline-time'>13:56</span>
</span>
</li>
<li>
<span class='speech-bubble'>
<span class='tremendous-giant-text'>See?</span>
<span class='inline-time'>13:56</span>
<span class='absolute-time'>13:56</span>
</span>
</li>
<li>
<span class='speech-bubble'>
Make the floated span invisible.
<span class='inline-time'>13:56</span>
</span>
</li>
<li>
<span class='speech-bubble'>
<span class='tremendous-giant-text'>See?</span>
<span class='inline-time hidden'>13:56</span>
<span class='absolute-time'>13:56</span>
</span>
</li>
<li>
<span class='speech-bubble'>
The giant text here is to simulate images which are common in a typical chat app.
<span class='tremendous-giant-text'>Done!</span>
<span class='inline-time hidden'>13:56</span>
<span class='absolute-time'>13:56</span>
</span>
</li>
</ul>
Here is the right solution:
.toBottomRight
{
display:inline-block;
position:fixed;
left:100%;
top:100%;
transform: translate(-100%, -100%);
white-space:nowrap;
background:red;
}
<div class="toBottomRight">Bottom-Right</div>
jsfiddle: https://jsfiddle.net/NickU/2k85qzxv/9/
Currently this is not possible. There are different approaches to solve aligning content to the bottom edge (flex, grid, table, absolute). However these approaches don't respect float and thus the content does not flow around these elements.
Someday floating elements could be possible with css if browsers and the csswg agrees on a definition.
Advanced resources:
https://drafts.csswg.org/css-page-floats/#float-property
https://github.com/w3c/csswg-drafts/issues/1251
If you need relative alignment and DIV's still aren't give you what you want, just use tables and set valign = "bottom" in the cell you want the content aligned to the bottom. I know it's not a great answer to your question since DIV's are supposed to replace tables, but this is what I had to do recently with an image caption and it has worked flawlessly so far.
I tried this scenario posted earlier also;
div {
position: absolute;
height: 100px;
top: 100%;
margin-top:-100px;
}
The absolute positioning fixes the div to the lowest part of the browser upon loading the page, but when you scroll down if the page is longer it does not scroll with you. I changed the positioning to be relative and it works perfect. The div goes straight to the bottom upon load so you won't actually see it until you get to the bottom.
div {
position: relative;
height:100px; /* Or the height of your image */
top: 100%;
margin-top: -100px;
}
Stu's answer comes the closest to working so far, but it still doesn't take into account the fact that your outer div's height may change, based on the way the text wraps inside of it. So, repositioning the inner div (by changing the height of the "pipe") only once won't be enough. That change has to occur inside of a loop, so you can continually check whether you've achieved the right positioning yet, and readjust if needed.
The CSS from the previous answer is still perfectly valid:
#outer {
position: relative;
}
#inner {
float:right;
position:absolute;
bottom:0;
right:0;
clear:right
}
.pipe {
width:0px;
float:right
}
However, the Javascript should look more like this:
var innerBottom;
var totalHeight;
var hadToReduce = false;
var i = 0;
jQuery("#inner").css("position","static");
while(true) {
// Prevent endless loop
i++;
if (i > 5000) { break; }
totalHeight = jQuery('#outer').outerHeight();
innerBottom = jQuery("#inner").position().top + jQuery("#inner").outerHeight();
if (innerBottom < totalHeight) {
if (hadToReduce !== true) {
jQuery(".pipe").css('height', '' + (jQuery(".pipe").height() + 1) + 'px');
} else { break; }
} else if (innerBottom > totalHeight) {
jQuery(".pipe").css('height', '' + (jQuery(".pipe").height() - 1) + 'px');
hadToReduce = true;
} else { break; }
}
I know it is a very old thread but still I would like to answer. If anyone follow the below css & html then it works. The child footer div will stick with bottom like glue.
<style>
#MainDiv
{
height: 300px;
width: 300px;
background-color: Red;
position: relative;
}
#footerDiv
{
height: 50px;
width: 300px;
background-color: green;
float: right;
position: absolute;
bottom: 0px;
}
</style>
<div id="MainDiv">
<div id="footerDiv">
</div>
</div>
Although this is very complicated but it is possible. I have check this code on latest Firefox and Google Chrome browser. Older browser may not support the css shape-outside property. For further detail check this reference.
window.addEventListener('load', function() {
var imageHolder = document.querySelector('.image-holder');
var containerHeight = document.querySelector('.container').offsetHeight;
var imageHolderHeight = imageHolder.offsetHeight;
var countPadding = containerHeight - imageHolderHeight;
imageHolder.style.paddingTop = countPadding + 'px';
containerHeight = document.querySelector('.container').offsetHeight;
var x1 = '0' + 'px ' + countPadding + 'px';
var x2 = imageHolder.offsetWidth + 'px' + ' ' + countPadding + 'px';
var x3 = imageHolder.offsetWidth + 'px' + ' ' + containerHeight + 'px';
var x4 = 0 + 'px' + ' ' + containerHeight + 'px';
var value = 'polygon(' + x1 + ',' + x2 + ',' + x3 + ',' + x4 + ')';
imageHolder.style.shapeOutside = value;
});
.container {
width: 300px;
text-align: justify;
border: 1px solid black;
}
.image-holder {
float: right;
}
<div class='container' style="">
<div class='image-holder' style=''>
<img class='bottom-right' style="width: 100px;" src="https://www.lwb.org.au/services/child-youth-and-family/static/b5cca79df7320248a77f6655a278190f/a6c62/img-index-banner.jpg" alt="">
</div>
<div>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Error quasi ut ipsam saepe, dignissimos, accusamus debitis ratione neque doloribus quis exercitationem iure! Harum quisquam ipsam velit distinctio tempora repudiandae eveniet.</div>
</div>
With some JavaScript I managed to pin a floated element to the bottom of its container - and still have it floated in the text, which is very useful for things like shape-outside.
The floated element gets a margin-top assigned that is equal to its container, its own height subtracted. This preserves the float, pushes the element to the bottom edge of its container and prevents text flowing below the element.
const resizeObserver = new ResizeObserver(entries => {
if(entries.length == 0) return;
const entry = entries[0];
if(!entry.contentRect) return;
const containerHeight = entry.contentRect.height;
const imgHeight = imgElem.height;
const imgOffset = containerHeight - imgHeight;
imgElem.style.marginTop = imgOffset + 'px';
});
const imgElem = document.querySelector('.image');
resizeObserver.observe(imgElem.parentElement);
Working example: https://codepen.io/strarsis/pen/QWGXGVy
Thanks to ResizeObserver and widespread support for JavaScript this seems to be a very reliable solution.
Try this CSS+Javascript solution. Start with a top right floating div. Then calculate the height for a zero-width div along the right edge to push your floating div to the bottom. This code may need some tweaking to get the right height.
<style>
#mainbox {border:4px solid red;width:500px;padding:10px;}
.rightpad {float:right;clear:right;padding:0;width:0;}
#floater {background-color:red;text-align:center;color:#FFF;width:300px;height:100px;float:right;margin-right:-10px;margin-top:10px;}
</style>
<script>
window.onload = function() {
var mmheight = document.getElementById("mainbox").clientHeight;
var ff = document.getElementById("floater");
var ffheight = ff.clientHeight;
var dd = document.createElement('div');
dd.className = "rightpad";
dd.style.height = (mmheight - ffheight - 20) * 1 + "px";
ff.parentNode.insertBefore(dd,ff);
}
</script>
<div id="mainbox">
<div id="floater" class="rightpad">123</div>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam posuere tellus et dolor vestibulum gravida. Donec vel nunc massa. Quisque quis varius libero. Fusce ut elementum magna. Praesent hendrerit diam sed velit rutrum mollis. Nunc pretium metus in tempus tempus. Quisque laoreet nibh eget volutpat dictum. Pellentesque libero ipsum, tristique et aliquam aliquam, accumsan sed sem. Phasellus facilisis sem eget mi tempus rhoncus.</p></div>
Pretty old question, but still ...
You can float a div to the bottom of the page like this:
div{
position: absolute;
height: 100px;
top: 100%;
margin-top:-100px;
}
You can see where the magic happens. I think you could do the same for floating it to the bottom of a parent div.
I'm currently trying to learn adaptive/mobile web-design, which involves media queries for different platforms and resolutions, using em rather than px in designs etc. I am currently trying to place two em-width elements next to each other; a navigation/info bar next to my content.
I have set the info bar to be 16em wide (translates into 16px per em according to font-size) and the content to be calc(100% - 17em) wide. I'd assume this should leave 1em of margin between the menu and the content, no matter how much I zoom and resize my window, but the end result disagrees:
100% zoom
25% zoom
friend's screen
The space between the elements changes vastly by zoom level, although everything universally uses 'em' units and the font-size is not changed between relevant elements. What could possibly be the issue?
Info: I'm using a media query to transition the navigation from horizontal alignment to a sidebar. It's the queried version that is acting up. Keep this in mind when looking over the CSS. It might be part of the problem, though I seriously doubt it...
#contentwrap {
margin-top: 1em;
border: 1px solid #000;
border-radius: 8px;
}
#content {
border-radius: 8px;
padding: 2em;
#navbar {
margin-top: 1em;
border: 1px solid #000;
border-radius: 8px;
width: 100%;
display: table;
font-family: 'Cabin', sans-serif;
}
.navelement {
font-size: 0.8em;
width: 25%;
padding: 1em;
text-align: center;
display: table-cell;
}
#nav4 {
}
#media (min-width:1580px) {
#navbar {
border: 1px dashed red;
padding: 0px;
width: 16em;
float: left;
background-image: none;
}
.navelement {
font-size: 0.8em;
background-image: url('../img/navbg.png');
background-size: 100% 100%;
width: 20em;
display: inherit;
border: 1px solid;
border-color: #303030 #101010 #101010 #101010;
border-radius: 8px;
margin-bottom: 1.25em;
padding: 1.25em;
}
#nav4 {
background-image: url('../img/navbg.png');
background-size: 100% 100%;
margin-bottom: 0em;
}
#contentwrap {
float: right;
width: -moz-calc(100% - 17em);
width: -webkit-calc(100% - 17em);
width: calc(100% - 17em);
}
}
HTML code:
<div id="navbar">
<div id="nav1" class="navelement"><b>Current news post:</b><br/>"Welcome to usp3!"<br/>by ividyon</div>
<div id="nav2" class="navelement"><b>Current MOTW:</b><br/>"Some Map"<br/>by some guy</br>[ Link to thread ]</div>
<div id="nav3" class="navelement"><b>Recent additions:</b><br/>- "Some map" review by Delacroix<br/>- Article: "Blah blah blah.." by ividyon<br/>- "Some other map" review by ividyon</div>
<div id="nav4" class="navelement">Recent forum posts:</br>- "This design is not good!"<br/>by A Dude</br>- "Too lazy to type filler..."<br/>by ividyon</br>- "Too lazy to type filler..."<br/>by ividyon</br>- "Too lazy to type filler..."<br/>by ividyon</div>
</div>
<div id="contentwrap">
<div id="content">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. In ut purus tortor. Maecenas ut semper dui, ac convallis libero. Vivamus molestie mauris a mauris pretium, et dignissim mauris dictum. Vivamus et interdum ipsum, vitae facilisis massa. In auctor convallis feugiat. Nulla sit amet accumsan ipsum. Sed risus felis, sodales ornare nisl a, scelerisque fringilla neque.</p>
</div>
</div>
The content of your #navbar is wider than the width you have given to the #navbar itself.
#navbar would be 16em+2px = 258px (at a font size of 16px), while the content would be 20em+2.5em+2px = 290px (at a font size of 12.8px).
And since the #navbar has display:table, its own width will adjust itself to the width of its children rather than let the content overflow out of its boundaries. Tables do that.
So, calc(100%-17em) for the remainder doesn't make it. Either calculate a smaller width, or, since the navbar has float:left anyway, you can leave out the width altogether! Simply set the left margin if desired and you're done.
See Fiddle.
I'm building a website that displays a vertically stacked list of comments that are placed by users.
The text should appear in a text balloon that basically displays the name of the user, there under the text and finally in the text balloon footer, it shows two links and floated to the right, a time stamp.
Since design/layouts are not my thing, it took me some painful days to achieve this in pure CSS (requirement) and I managed to make the list appear very neatly. For that I have tried to study the CSS that Google and Twitter use to show resp their video's and Tweets and try to extract some useful stuff from it. However, I noticed their CSS's and HTML are huge and I'm questioning if they did it the "right" way or if they found out that was the only possibility in order to make it display well on all types of devices. (Can somebody shed some light on that perhaps?) Conclusion is that it was not very useful for me.
However, the result doesn't feel good and is very "touchy" (not flexible at all); for instance, when I resize my window or open the page on my tablet, it just looks disgusting; text block wrapped and displayed under the avatar image...
Question 1: as I mentioned, I have been looking /studying a lot by looking how the big sites (such as YouTube, Twitter and FaceBook) doing similar things and the HTML/CSS looks a bit messy in my opinion. Anybody sharing that thought/opinion?
Question 2: can someone provide me a with good starting point, i.e. HTML/CSS Example (preferably in a JSFiddle or so) for the following:
Some remarks:
No images should be used (expect from the avatar image offcourse)
No tables should be used; only Div's and/or HTML-5 sementics (such as header, footer, article, and so on)
The CSS/HTML layout should be that flexible that it adjust itself properly. On the image you can how I would like to have it displayed in different scenarios.
Should display well in latest version in IE, FireFox, Safari and Chrome.
Given the following mark-up:
<div class="wrap">
<img src="http://davidrhysthomas.co.uk/img/dexter.png" />
<div class="comment" data-owner="Dexter">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque lacus lacus, blandit sit amet iaculis sodales, eleifend ut massa. Mauris arcu felis, facilisis sed bibendum et, tristique tincidunt dolor. Cras a hendrerit nisl. Maecenas accumsan, urna at aliquam blandit, ipsum erat pellentesque urna, et interdum mauris lacus et tellus.</p>
<ol class="postscript"> <!-- links and timestamp -->
<li>link 1</li>
<li>link 2</li>
<li class="date">3 days ago</li>
</ol>
</div>
</div>
And the following CSS:
div.wrap {
width: 90%;
margin: 0 auto 1em auto;
position: relative; /* the image will be absolutely-positioned relative to this */
}
div.wrap:first-child {
margin-top: 1em; /* just for aesthetic reasons, adjust or remove, to taste */
}
div.comment {
font-size: 1em;
position: relative; /* the arrow on the left side of the div positioned relative to this element */
margin-left: 60px; /* allows a 10px gutter for the arrow to fit into */
border-radius: 0.75em 0.75em 0.75em 0.75em;
background-color: #ccc;
line-height: 1.4em;
font-family: Helvetica; /* or whatever... */
}
div.comment::before { /* requires a fairly modern browser */
content: attr(data-owner); /* displays the name of the comment-owner */
border-radius: 0.75em 0.75em 0 0;
background-color: #ccc;
display: block;
text-indent: 10%; /* adjust to taste */
border-bottom: 3px solid #999;
}
div.comment::after { /* again, requires a fairly modern browser */
content: ''; /* this property is necessary, even if only an empty string */
position: absolute;
top: 50%;
left: 0;
border: 10px solid transparent;
border-right: 10px solid #ccc; /* forms the 'arrow' */
margin: -10px 0 0 -20px;
}
div.comment p { /* or whatever, adjust to taste */
width: 80%;
margin: 0 auto 1em auto;
padding-bottom: 1em;
}
img {
position: absolute;
top: 50%;
width: 50px;
float: left;
border-radius: 10px;
margin-top: -25px;
}
p + ol.postscript {
width: 80%;
font-size: 0.8em;
margin: -0.5em auto 0 auto;
}
ol.postscript::after {
content: '';
height: 0.5em;
display: block;
clear: both;
}
ol.postscript li {
float: left;
margin-right: 0.5em;
}
ol.postscript li.date {
float: right;
margin-right: 0;
}
.wrap a:link,
.wrap a:visited {
color: #333;
text-decoration: none;
border-bottom: 1px solid #333;
}
.wrap a:hover,
.wrap a:active,
.wrap a:focus {
color: #f00;
border-bottom: 1px solid #f00;
}
JS Fiddle demo.
Edited in response to the valid comments, left below:
I don't think screen readers reads attributes which means it would probably be better to put the content of data-owner inside its own element, instead of an attribute.
One quibble (as noted above too) [Screenreaders will not read CSS generated content](One quibble (as noted above too) Screenreaders will not read CSS generated content and the comment author seems to me to be an essential bit of content that should be accessible to screenreader users.) and the comment author seems to me to be an essential bit of content that should be accessible to screenreader users.
Given the sound advice, I've replaced the .comment::before element, adding a discrete h2:
<div class="wrap">
<img src="http://davidrhysthomas.co.uk/img/dexter.png" />
<div class="comment" data-owner="Dexter">
<h2 class="owner">Dexter</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque lacus lacus, blandit sit amet iaculis sodales, eleifend ut massa. Mauris arcu felis, facilisis sed bibendum et, tristique tincidunt dolor. Cras a hendrerit nisl. Maecenas accumsan, urna at aliquam blandit, ipsum erat pellentesque urna, et interdum mauris lacus et tellus.</p>
<ol class="postscript">
<li>link 1</li>
<li>link 2</li>
<li class="date">3 days ago</li>
</ol>
</div>
</div>
and appended the following CSS (in place of the original .comment::before):
div.comment p {
width: 80%;
margin: 0 auto 1em auto;
}
Revised JS Fiddle.
I have floated images and inset boxes at the top of a container using float:right (or left) many times. Now, I need to float a div to the bottom right corner of another div with the normal text wrap that you get with float (text wrapped above and to the left only).
I thought this must be relatively easy even though float has no bottom value but I haven't been able to do it using a number of techniques and searching the web hasn't come up with anything other than using absolute positioning but this doesn't give the correct word wrap behaviour.
I had thought this would be a very common design but apparently it isn't. If nobody has a suggestion I'll have to break my text up into separate boxes and align the div manually but that is rather precarious and I'd hate to have to do it on every page that needs it.
Set the parent div to position: relative, then the inner div to...
position: absolute;
bottom: 0;
...and there you go :)
A way to make it work is the following:
Float your elements left like normal
Rotate the parent div 180 degrees using
-moz-transform:rotate(180deg);
-webkit-transform:rotate(180deg);
-o-transform:rotate(180deg);
-ms-transform:rotate(180deg);
filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);
JSfiddle: http://jsfiddle.net/wcneY/
Now rotate all the elements that float left (give them a class) 180 degrees to put them straight again. Voila! they float to the bottom.
After struggling with various techniques for a couple of days I have to say that this appears to be impossible. Even using javascript (which I don't want to do) it doesn't seem possible.
To clarify for those who may not have understood - this is what I am looking for: in publishing it is quite common to layout an inset (picture, table, figure, etc.) so that its bottom lines up with the bottom of the last line of text of a block (or page) with text flowing around the inset in a natural manner above and to the right or left depending on which side of the page the inset is on. In html/css it is trivial to use the float style to line up the top of an inset with the top of a block but to my surprise it appears impossible to line up the bottom of the text and inset despite it being a common layout task.
I guess I'll have to revisit the design goals for this item unless anyone has a last minute suggestion.
I have acheived this in JQuery by putting a zero width strut element above the float right, then sizing the strut (or pipe) according to parent height minus floated child's height.
Before js kicks in I am using the position absolute approach, which works but allows text flow behind. Therefore I switch to position static to enable the strut approach.
(header is the parent element, cutout is the one i want bottom right, and pipe is my strut)
$("header .pipe").each(function(){
$(this).next(".cutout").css("position","static");
$(this).height($(this).parent().height()-$(this).next(".cutout").height());
});
CSS
header{
position: relative;
}
header img.cutout{
float:right;
position:absolute;
bottom:0;
right:0;
clear:right
}
header .pipe{
width:0px;
float:right
}
The pipe must come 1st, then the cutout, then the text in the HTML order.
This puts a fixed div at the bottom of the page and fixes to the bottom as you scroll down
#div {
left: 0;
position: fixed;
text-align: center;
bottom: 0;
width: 100%;
}
Put the div in another div and set the parent div's style to position:relative; Then on the child div set the following CSS properties: position:absolute; bottom:0;
If you set the parent element as position:relative, you can set the child to the bottom setting position:absolute; and bottom:0;
#outer {
width:10em;
height:10em;
background-color:blue;
position:relative;
}
#inner {
position:absolute;
bottom:0;
background-color:white;
}
<div id="outer">
<div id="inner">
<h1>done</h1>
</div>
</div>
If you're okay with only the bottom-most line of the text going to the side of the block (as opposed to completely around and underneath it, which you can't do without ending the block and starting a new one), it's not impossible to float a block to one of the bottom corners of a parent block. If you put some content in a paragraph tag within a block and want to float a link to the bottom right corner of the block, put the link within the paragraph block and set it to float: right, then put in a div tag with clear: both set just underneath the end of the paragraph tag. The last div is to make sure the parent tag surrounds the floated tags.
<div class="article" style="display: block;">
<h3>title</h3>
<p>
text content
Read More
</p>
<div style="clear: both;"></div>
</div>
With the introduction of Flexbox, this has become quite easy without much hacking. align-self: flex-end on the child element will align it along the cross-axis.
.container {
display: flex;
}
.bottom {
align-self: flex-end;
}
<div class="container">
<div class="bottom">Bottom of the container</div>
</div>
Output:
.container {
display: flex;
/* Material design shadow */
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12);
height: 100px;
width: 175px;
padding: 10px;
background: #fff;
font-family: Roboto;
}
.bottom {
align-self: flex-end;
}
<div class="container">
<div class="bottom">Bottom of the container</div>
</div>
I had been find this solution for a long time as well.
This is what I get:
align-self: flex-end;
link: https://philipwalton.github.io/solved-by-flexbox/demos/vertical-centering/
However, I can't remember from where I opened this link. Hope it helps
If you want the text to wrap nicely:-
.outer {
display: table;
}
.inner {
height: 200px;
display: table-cell;
vertical-align: bottom;
}
/* Just for styling */
.inner {
background: #eee;
padding: 0 20px;
}
<!-- Need two parent elements -->
<div class="outer">
<div class="inner">
<h3>Sample Heading</h3>
<p>Sample Paragragh</p>
</div>
</div>
This is now possible with flex box.
Just set the 'display' of parent div as 'flex' and set the 'margin-top' property to 'auto'.
This does not distort any property of both the div.
.parent {
display: flex;
height: 100px;
border: solid 1px #0f0f0f;
}
.child {
margin-top: auto;
border: solid 1px #000;
width: 40px;
word-break: break-all;
}
<div class=" parent">
<div class="child">I am at the bottom!</div>
</div>
I know that this stuff is old, but I recently ran into this problem.
use absolute position divs advice is really silly, because the whole float thing kind of loses point with absolute positions..
now, I did not find an universal solution, but in a lot of cases prople use floating divs just to display something in a row, like a series of span elements. and you can't vertically align that.
to achieve a similar effect you can do this: do not make the div float, but set it's display property to inline-block. then you can align it vertically however it pleases you. you just need to set parent's div property vertical-align to either top, bottom, middle or baseline
i hope that helps someone
One interesting approach is to stack a couple of right float elements on top of each other.
<div>
<div style="float:right;height:200px;"></div>
<div style="float:right;clear:right;">Floated content</div>
<p>Other content</p>
</div>
Only problem is that this only works when you know the height of the box.
I would just do a table.
<div class="elastic">
<div class="elastic_col valign-bottom">
bottom-aligned content.
</div>
</div>
And the CSS:
.elastic {
display: table;
}
.elastic_col {
display: table-cell;
}
.valign-bottom {
vertical-align: bottom;
}
See it in action:
http://jsfiddle.net/mLphM/1/
I tried several of these techniques, and the following worked for me, so if all else here if all else fails then try this because it worked for me :).
<style>
#footer {
height:30px;
margin: 0;
clear: both;
width:100%;
position: relative;
bottom:-10;
}
</style>
<div id="footer" >Sportkin - the registry for sport</div>
A chose this approach of #dave-kok. But it works only if the whole content suits without scrolling. I appreciate if somebody will improve
outer {
position: absolute;
bottom: 0;
width: 100%;
height: 100%;
}
.space {
float: right;
height: 75%;
}
.floateable {
width: 40%;
height: 25%;
float: right;
clear: right;
}
Here is code http://jsfiddle.net/d9t9joh2/
Not sure, but a scenario posted earlier seemed to work if you use position: relative instead of absolute on the child div.
#parent {
width: 780px;
height: 250px;
background: yellow;
border: solid 2px red;
}
#child {
position: relative;
height: 50px;
width: 780px;
top: 100%;
margin-top: -50px;
background: blue;
border: solid 2px green;
}
<div id="parent">
This has some text in it.
<div id="child">
This is just some text to show at the bottom of the page
</div>
</div>
And no tables...!
To use css margin-top property with purpose to set footer to the bottom of its container. And to use css text-align-last property to set the footer contents at center.
<div class="container" style="margin-top: 700px; text-align-last: center; ">
<p>My footer Here</p>
</div>
A combination of floating and absolute positioning does the work for me. I was attempting to place the send time of a message at the bottom-right corner of the speech bubble. The time should never overlap the message body and it will not inflate the bubble unless it's really necessary.
The solution works like this:
there're two spans with identical text;
one is floated but invisible;
the other is absolutely positioned to the corner;
The purpose of the invisible floated one is to ensure space for the visible one.
.speech-bubble {
font-size: 16px;
max-width: 240px;
margin: 10px;
display: inline-block;
background-color: #ccc;
border-radius: 5px;
padding: 5px;
position: relative;
}
.inline-time {
float: right;
padding-left: 10px;
color: red;
}
.giant-text {
font-size: 36px;
}
.tremendous-giant-text {
font-size: 72px;
}
.absolute-time {
position: absolute;
color: green;
right: 5px;
bottom: 5px;
}
.hidden {
visibility: hidden;
}
<ul>
<li>
<span class='speech-bubble'>
This text is supposed to wrap the time <span> which always seats at the corner of this bubble.
<span class='inline-time'>13:55</span>
</span>
</li>
<li>
<span class='speech-bubble'>
Absolute positioning doesn't work because it doesn't care if the two pieces of text overlap. We want to float.
<span class='inline-time'>13:55</span>
</span>
</li>
<li>
<span class='speech-bubble'>
Easy, uh?
<span class='inline-time'>13:55</span>
</span>
</li>
<li>
<span class='speech-bubble'>
Well, not <span class='giant-text'>THAT</span>
easy
<span class='inline-time'>13:56</span>
</span>
</li>
<li>
<span class='speech-bubble'>
<span class='tremendous-giant-text'>See?</span>
<span class='inline-time'>13:56</span>
</span>
</li>
<li>
<span class='speech-bubble'>
The problem is, we can't tell the span to float to right AND bottom...
<span class='inline-time'>13:56</span>
</span>
</li>
<li>
<span class='speech-bubble'>
We can combinate float and absolute: use floated span to reserve space (the bubble will be inflated if necessary) so that the absoluted span is safe to go.
<span class='inline-time'>13:56</span>
</span>
</li>
<li>
<span class='speech-bubble'>
<span class='tremendous-giant-text'>See?</span>
<span class='inline-time'>13:56</span>
<span class='absolute-time'>13:56</span>
</span>
</li>
<li>
<span class='speech-bubble'>
Make the floated span invisible.
<span class='inline-time'>13:56</span>
</span>
</li>
<li>
<span class='speech-bubble'>
<span class='tremendous-giant-text'>See?</span>
<span class='inline-time hidden'>13:56</span>
<span class='absolute-time'>13:56</span>
</span>
</li>
<li>
<span class='speech-bubble'>
The giant text here is to simulate images which are common in a typical chat app.
<span class='tremendous-giant-text'>Done!</span>
<span class='inline-time hidden'>13:56</span>
<span class='absolute-time'>13:56</span>
</span>
</li>
</ul>
Here is the right solution:
.toBottomRight
{
display:inline-block;
position:fixed;
left:100%;
top:100%;
transform: translate(-100%, -100%);
white-space:nowrap;
background:red;
}
<div class="toBottomRight">Bottom-Right</div>
jsfiddle: https://jsfiddle.net/NickU/2k85qzxv/9/
Currently this is not possible. There are different approaches to solve aligning content to the bottom edge (flex, grid, table, absolute). However these approaches don't respect float and thus the content does not flow around these elements.
Someday floating elements could be possible with css if browsers and the csswg agrees on a definition.
Advanced resources:
https://drafts.csswg.org/css-page-floats/#float-property
https://github.com/w3c/csswg-drafts/issues/1251
If you need relative alignment and DIV's still aren't give you what you want, just use tables and set valign = "bottom" in the cell you want the content aligned to the bottom. I know it's not a great answer to your question since DIV's are supposed to replace tables, but this is what I had to do recently with an image caption and it has worked flawlessly so far.
I tried this scenario posted earlier also;
div {
position: absolute;
height: 100px;
top: 100%;
margin-top:-100px;
}
The absolute positioning fixes the div to the lowest part of the browser upon loading the page, but when you scroll down if the page is longer it does not scroll with you. I changed the positioning to be relative and it works perfect. The div goes straight to the bottom upon load so you won't actually see it until you get to the bottom.
div {
position: relative;
height:100px; /* Or the height of your image */
top: 100%;
margin-top: -100px;
}
Stu's answer comes the closest to working so far, but it still doesn't take into account the fact that your outer div's height may change, based on the way the text wraps inside of it. So, repositioning the inner div (by changing the height of the "pipe") only once won't be enough. That change has to occur inside of a loop, so you can continually check whether you've achieved the right positioning yet, and readjust if needed.
The CSS from the previous answer is still perfectly valid:
#outer {
position: relative;
}
#inner {
float:right;
position:absolute;
bottom:0;
right:0;
clear:right
}
.pipe {
width:0px;
float:right
}
However, the Javascript should look more like this:
var innerBottom;
var totalHeight;
var hadToReduce = false;
var i = 0;
jQuery("#inner").css("position","static");
while(true) {
// Prevent endless loop
i++;
if (i > 5000) { break; }
totalHeight = jQuery('#outer').outerHeight();
innerBottom = jQuery("#inner").position().top + jQuery("#inner").outerHeight();
if (innerBottom < totalHeight) {
if (hadToReduce !== true) {
jQuery(".pipe").css('height', '' + (jQuery(".pipe").height() + 1) + 'px');
} else { break; }
} else if (innerBottom > totalHeight) {
jQuery(".pipe").css('height', '' + (jQuery(".pipe").height() - 1) + 'px');
hadToReduce = true;
} else { break; }
}
I know it is a very old thread but still I would like to answer. If anyone follow the below css & html then it works. The child footer div will stick with bottom like glue.
<style>
#MainDiv
{
height: 300px;
width: 300px;
background-color: Red;
position: relative;
}
#footerDiv
{
height: 50px;
width: 300px;
background-color: green;
float: right;
position: absolute;
bottom: 0px;
}
</style>
<div id="MainDiv">
<div id="footerDiv">
</div>
</div>
Although this is very complicated but it is possible. I have check this code on latest Firefox and Google Chrome browser. Older browser may not support the css shape-outside property. For further detail check this reference.
window.addEventListener('load', function() {
var imageHolder = document.querySelector('.image-holder');
var containerHeight = document.querySelector('.container').offsetHeight;
var imageHolderHeight = imageHolder.offsetHeight;
var countPadding = containerHeight - imageHolderHeight;
imageHolder.style.paddingTop = countPadding + 'px';
containerHeight = document.querySelector('.container').offsetHeight;
var x1 = '0' + 'px ' + countPadding + 'px';
var x2 = imageHolder.offsetWidth + 'px' + ' ' + countPadding + 'px';
var x3 = imageHolder.offsetWidth + 'px' + ' ' + containerHeight + 'px';
var x4 = 0 + 'px' + ' ' + containerHeight + 'px';
var value = 'polygon(' + x1 + ',' + x2 + ',' + x3 + ',' + x4 + ')';
imageHolder.style.shapeOutside = value;
});
.container {
width: 300px;
text-align: justify;
border: 1px solid black;
}
.image-holder {
float: right;
}
<div class='container' style="">
<div class='image-holder' style=''>
<img class='bottom-right' style="width: 100px;" src="https://www.lwb.org.au/services/child-youth-and-family/static/b5cca79df7320248a77f6655a278190f/a6c62/img-index-banner.jpg" alt="">
</div>
<div>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Error quasi ut ipsam saepe, dignissimos, accusamus debitis ratione neque doloribus quis exercitationem iure! Harum quisquam ipsam velit distinctio tempora repudiandae eveniet.</div>
</div>
With some JavaScript I managed to pin a floated element to the bottom of its container - and still have it floated in the text, which is very useful for things like shape-outside.
The floated element gets a margin-top assigned that is equal to its container, its own height subtracted. This preserves the float, pushes the element to the bottom edge of its container and prevents text flowing below the element.
const resizeObserver = new ResizeObserver(entries => {
if(entries.length == 0) return;
const entry = entries[0];
if(!entry.contentRect) return;
const containerHeight = entry.contentRect.height;
const imgHeight = imgElem.height;
const imgOffset = containerHeight - imgHeight;
imgElem.style.marginTop = imgOffset + 'px';
});
const imgElem = document.querySelector('.image');
resizeObserver.observe(imgElem.parentElement);
Working example: https://codepen.io/strarsis/pen/QWGXGVy
Thanks to ResizeObserver and widespread support for JavaScript this seems to be a very reliable solution.
Try this CSS+Javascript solution. Start with a top right floating div. Then calculate the height for a zero-width div along the right edge to push your floating div to the bottom. This code may need some tweaking to get the right height.
<style>
#mainbox {border:4px solid red;width:500px;padding:10px;}
.rightpad {float:right;clear:right;padding:0;width:0;}
#floater {background-color:red;text-align:center;color:#FFF;width:300px;height:100px;float:right;margin-right:-10px;margin-top:10px;}
</style>
<script>
window.onload = function() {
var mmheight = document.getElementById("mainbox").clientHeight;
var ff = document.getElementById("floater");
var ffheight = ff.clientHeight;
var dd = document.createElement('div');
dd.className = "rightpad";
dd.style.height = (mmheight - ffheight - 20) * 1 + "px";
ff.parentNode.insertBefore(dd,ff);
}
</script>
<div id="mainbox">
<div id="floater" class="rightpad">123</div>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam posuere tellus et dolor vestibulum gravida. Donec vel nunc massa. Quisque quis varius libero. Fusce ut elementum magna. Praesent hendrerit diam sed velit rutrum mollis. Nunc pretium metus in tempus tempus. Quisque laoreet nibh eget volutpat dictum. Pellentesque libero ipsum, tristique et aliquam aliquam, accumsan sed sem. Phasellus facilisis sem eget mi tempus rhoncus.</p></div>
Pretty old question, but still ...
You can float a div to the bottom of the page like this:
div{
position: absolute;
height: 100px;
top: 100%;
margin-top:-100px;
}
You can see where the magic happens. I think you could do the same for floating it to the bottom of a parent div.