Is there any way to get the content text of a div to the bottom of it?
Here I've prepared an example.
http://jsfiddle.net/JGuP7/
This is the sample hierarchy:
<div class="button">Button Label</div>
I'm trying to achieve the result without adding additional spans or changing the hierarchy.
Three possible solutions, although each has its own caveats.
jsFiddle demo
The first solution relies on line-height: 220px; vertical-align: bottom; to align the text with the bottom of the DIV. The second solution creates a :before psuedo-element that pushes the text to the bottom of the DIV (this requires no additional markup). Both solutions will fail in IE7 or earlier, and both will have issues if:
The font size changes
The text wraps to a second line
The size of the containing element changes
The third solution relies on the display: box; property, which is a CSS property that is being phased out (more details at Quick Hits With the Flexible Box Model). This solution is only supported by Chrome since v4, Firefox since v2, and IE10 beta. However, a new Flexbox standard has been standardized, but browser support is minimal. This solution could be considered "too new" to be used effectively (html5please.com/#flexbox).
Generally speaking, you should consider a new wrapping element around your text which will allow for position: absolute; bottom: 0; to cozy the element to the bottom of the parent element. This has the benefit of growing the child element upwards as the font size or text length increases, and is agnostic to the parent container's dimensions. Depending on how mission critical your positioning is to your layout, you could add this new element using Javascript. This probably isn't ideal given the question you've posed, but browser support isn't less than ideal for the more wacky CSS solutions I've listed above :-p
Another way to to do this would be by using "display: table-cell" and "vertical-align: bottom".
http://jsfiddle.net/JGuP7/1/
.button {
display: table-cell;
background-color: darkred;
color: white;
width: 120px;
height: 120px;
text-align: center;
vertical-align: bottom;
}
If you use position:relative in the container, and use
position:absolute;
bottom:0;
in the content, you can achieve the desired result.
Your CSS might look like:
.button
{
display: block;
background-color: darkred;
color: white;
width: 120px;
height: 120px;
text-align: center;
position: relative;
}
.bottomContent
{
position:absolute;
bottom: 0;
}
and your HTML:
<div class="button"><p class="bottomContent">Button Label</p></div>
Source
Related
I want a paragraph inside an absolutely positioned element to break the text at a specified max-width, but not fill the entire space if the content is smaller.
<p>Text
<span class="cite">Reference
<span class="citeBox">A long sentence that needs to have a line break.</span>
</span>.
Text
<span class="cite">Reference
<span class="citeBox">Short</span>
</span>
Text.
</p>
.cite {
position: relative;
}
.cite .citeBox {
position: absolute;
max-width: 400px;
left: 0;
/*...*/
}
http://jsfiddle.net/8ebsLc6L/1/
That is, the Short-Box should only be small and the Big-Box should break at 400px. All boxes need to dynamically move with the reference span.
The current code does not expand the Big-Box to 400px.
The solution should not require Javascript.
Would much appreciate your help!
I believe it is not possible to achieve what you want by only modifying your CSS.
However, I think I managed it by adding another <span> element.
The problem here is that the width of .cite is passed down to its children.
But you can work around that by adding another element between them with
position: absolute;
with: 400px;
Such an element will be invisible by default, but it will catch mouse events, so you might want to prevent that, using
pointer-events: none;
From the most inner element, you can now remove the position, left and bottom attributes, but instead add
display: inline-block;
This is necessary in order to display the box as a block in case the text requires more than one line, but still keep it at the lowest width and height possible.
And you might want to re-enable pointer events on the most inner element too:
pointer-events: all;
All the above packed into a fiddle: http://jsfiddle.net/8ebsLc6L/4/
Here is one way of doing it.
Wrap your text in a span element, .citeWrap, and assign the background color, border-radius and so on. Note that you do not need the max-width property anymore.
For .citeBox, set width: 400px.
What will happen is that the .citeWrap will use the 400px as the working width to lay out the text and the line box will be no longer than 400px.
However, if the text is shorter than 400px, the span, being an inline element, will have a shrink-to-fit width, so you will get the background color just covering the text.
.cite {
position: relative;
color: blue;
}
.cite .citeBox {
position: absolute;
width: 400px;
left: 0;
bottom: 20px;
}
.cite .citeWrap {
padding: 5px 15px;
background-color: rgba(0, 0, 0, .6);
border-radius: 5px;
color: #fff;
font-size: 1.2rem;
display: inline-block;
}
p {
margin-top: 4.0em; /* for demo only */
)
<p>To visualize an algorithm, we don’t merely fit data to a chart; there is no primary dataset. Instead there are logical rules that describe behavior. This may be why algorithm visualizations are so unusual, as designers experiment with novel forms to better communicate. Here is Brets wonderful
<span class="cite">Reference<span class="citeBox"><span class="citeWrap">A long sentence that needs to have a line break. Make it a bit longer and you see multiple lines.</span></span></span>.
To visualize an algorithm, we don’t merely fit data to a chart; there is no primary dataset. Instead there are logical rules that describe behavior. This may be why algorithm visualizations are so unusual, as designers experiment with
<span class="cite">Reference<span class="citeBox"><span class="citeWrap">Short</span></span></span>
novel forms to better communicate. Here is Brets.</p>
I have three containers (div), the third div has a set width but I need the other two to be responsive. Current html setup:
<div id="page-type">
<div id="type-container">
<div>
<p id="type-title">Events</p>
</div>
</div>
<div class="type-options">
</div>
<div id="type-back">
Back to Explore
</div>
</div>
Current css:
#page-type {
float: left;
width: 100%;
background: #D2D3D5;
height: 60px;
}
#type-container {
float: left;
width: auto;
}
#type-options {
height: 60px;
width: auto;
overflow: hidden;
}
#type-back {
border-left: 1px #BDBEC1 solid;
float: right;
width: 160px;
}
I can get type-container and type-options to be on the same line and responsive but I can't keep type-back on the same line.
visual example:
----- EDIT -----
To clarify more:
type-container adjusts to fit it's content
type-back is a set width
type-option fills in the space between type-container and type-back regardless of content
type-containerand type-options fill up the whole row pushing type-back to the next line. I need type-back to stay to the right of the line while the other two are responsive.
Put a wrapper around your first two columns and then you can use CSS3's calc().
#wrapper {
width: calc(100% - 161px); /* extra px for 1px border */
float: left;
}
Demo here
IE8 Workaround - Use border-box:
#wrapper {
margin-right: -161px;
padding-right: 161px;
width: 100%;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
IE8 Demo
In CSS3 you can use calc(X% - 160px) to reduce the width of a percentage based container by a number of pixels.
A quick example could be: http://jsfiddle.net/e3vC4/
There isn't a need to use calc for this, even though its a nice feature to have (+1) — sadly its support is still patchy in places and despite much research it's still difficult to say exactly which browser versions will work as expected (fine if you assume all modern browser users auto-upgrade however).
Depending on what your prerequisites are, you have two other options that I'm aware of:
1. Position absolute the last column
This is a simple solution, however something to be wary of is that certain older mobile devices may treat position absolute in odd ways.
In order to get this to work, all you need to do is place position: relative on your container, and position: absolute; right: 0; top: 0; on your third column... and to keep the centering of your central column correct, add margin-right: 161px.
Pos. Abs. example on JSFiddle
CSS ~ markup is as per your example
#page-type {
display: block;
position: relative; /* added */
width: 100%;
background: #D2D3D5;
height: 60px;
overflow: hidden;
}
#type-container {
display: block;
float: left;
text-align: center;
}
#type-options {
display: block;
height: 100%;
text-align: center;
overflow: hidden;
margin-right: 161px; /* added */
}
#type-back {
display: block;
position: absolute; /* added */
right: 0; /* added */
top: 0; /* added */
border-left: 1px #BDBEC1 solid;
width: 160px;
height: 100%;
}
2. Float right, and/or left, before sibling without hasLayout / shrinkwrap
This works on the basis that a floated element takes up space in the document, and a block element, by default, auto-expands to fill the remaining area that it can — as long as it hasn't been forced to rigidly define its edges with the likes of float, overflow or other hasLayout or shrinkwrap tricks.
This option is only open to you if you can re-arrange your DOM ordering i.e. place #type-back before #type-options. This won't affect the visual order, but it makes a big difference to how the layout is calculated, and is one of the reasons why you were encountering problems with your attempts. You need to have the floated elements in place before leaving the other elements to calculate their dimensions.
Float example on JSFiddle
NOTE: Changing the order of DOM elements can be of benefit, but it can also be a hindrance; it all depends on what the markup is, and who will be viewing it. For example, sometimes having actionable links higher up the DOM can be useful to tabbing and screen-reader users, but the opposite can also be true depending on the context.
MARKUP ~ note the rearranged DOM order
<div id="page-type">
<div id="type-container">
<p id="type-title">Events</p>
</div>
<div id="type-back">
<p>Back to Explore</p>
</div>
<div id="type-options">
<p>Options</p>
</div>
</div>
CSS
#page-type {
display: block;
width: 100%;
background: #D2D3D5;
height: 60px;
overflow: hidden;
}
#type-container {
display: block;
float: left;
text-align: center;
}
#type-options {
display: block;
height: 100%;
text-align: center;
overflow: hidden;
}
#type-back {
float: right;
border-left: 1px #BDBEC1 solid;
width: 160px;
height: 100%;
}
NOTE: It should be stated this version does break on to the next line when "responsed" down to a very minimal size. However, I tend to prefer to design items to disappear when space is tight, and this method lends well to that thinking.
Summary
These are just two other possible options. If you are developing for a progressive client, or yourself, then I personally would stick with the calc method. It's easier to work out what is going on, and far easier for a future developer to change.
However, sometimes often frequently all the blasted time clients want to support the widest range of devices possible (without investing the extra time and money that would be required), and in this instance you are better off with an alternative method (one that isn't going to randomly break on a manager's less than contemporary laptop, running IE 7.5? or 8.33333??? or even Netscape 4.7¿).
Unless of course, you have any leeway to fight for using the more progressive approach, which does seem to be getting easier of late.
I sat down with the designer for more clarification and to discuss alternate solutions. I'm making the third did responsive as well allowing me to use two containers: one holds page-type and type-options set to x% and another holds type-back set to y%. Doing this allows me to keep all elements responsive.
I want to know is there a way to centre text vertically without the use of a container element. something which is responsive.
EDIT
the only value I would know is the height of the h3 element, nothing more,
content will appear underneath some as etc
CSS
h3 {
height: 140px;
padding-top: 80px;
min-height: inherit;
border: 1px solid black;
text-align: center;
}
HTML
<h3>TEST</h3>
Here is an example of what i want to achieve
codepen test
Line-height is a beautiful thing, especially if its just text. And if you want to be responsive:
h3 {
background-color: transparent;
height: 40vh;
line-height: 40vh;
min-height: inherit;
border: 1px solid black;
text-align: center;
}
There is no easy way to do this. I have come up with a couple techniques over the years.
You have 80px in padding and a height of 140px for a combined height of 240px. If you know that the text will not exceed one line you can do it using line-height.
h3{
line-height:240px;
...
}
Another way is to use padding if you know the height of your text.
h3{
font-size: 20px;
line-height:20px;
padding:110px 0;/* (240-20)/2 */
...
}
note: I don't like the display: table-cell hack and have yet to need it. Why move away from a table based layout if you're just going to tell the browser to treat the element as a table?
Add to your code:
display: table-cell;
vertical-align: middle;
You will need to adjust your padding. That should work.
This article provides 6 different methods and their associated pros and cons; it explains it far better than I could here. The solutions provided as answers here are good, but the article really covers niche cases and allows you to choose the best method to fit your needs.
http://www.vanseodesign.com/css/vertical-centering/
You're going to have a containing element, regardless. It's just that the body might be the container.
You could do this:
body {
height:100%;
display: table;
margin: 0px;
padding: 0px;
}
h3 {
display: table-cell;
vertical-align: middle;
}
OR...
body {
height:100%;
margin: 0px;
padding: 0px;
}
h3 {
position: relative;
top: 50%;
}
edit - removed width specific styles as it has nothing to do with the solution. Thanks to Jason for the margin/padding set to 0px to remove ugly scrollbars. Jason also noted that this solution did not work for Chrome unless the "body" element in the styles was changed to "html, body", but I was not able to replicate this problem using Chrome version 35.0... For good measure I also opened a test page in Safari and Firefox and they also worked as expected.
edit^2 - Figured out the problem Jason saw. If you use the html5 doctype, then, yes, you will have to include the html element with the body style. This also makes the scrollbar reappear in the relative position solution. So that's fun. I will leave this up for the purpose of saving frustration in the future, but I would check out the link provided in Jason's solution.
http://phrogz.net/CSS/vertical-align/
How can I vertically center text in a dynamically height div?
sorry if the question title is weak, i can't quite sum my problem up into one snappy tagline...
I'm working on a website (using Joomla) and i've had to insert a DIV serving as a sidebar on the right side of the page. in order for it to be displayed "above" (or "over", i mean on the z-axis) the regular page content, i'm using a negative margin on the left side of it, covering the whole width of it, so it will simply float to the right and sit there, which works fine in ff and IE.
Since i've rarely ever run into issues with Chrome that were fine in IE, i didn't bother to check until quite late:
Now i see that in Chrome, the div is just sitting below (at the bottom of) the regular content; despite the "inline" display-types and the negative margin.
Now I've tried ridiculous things to make it work, but for some reason it just won't.
Can someone tell me how i can get it to work in Chrome?
HTML:
<div class="cframe">
<div class="content">
...
</div>
<div class="sideright">
...
</div>
</div>
CSS:
div.cframe {
display: table;
vertical-align: top;
}
div.content {
display: inline-table;
width: 751px;
padding: 60px;
}
DIV.sideright {
width: 200px;
float: right;
display: block;
position: relative;
top: 320px;
margin: 0px 0px 0px -200px;
}
...this is what i'm stuck with right now, it's all quite ugly.
[link to live-page removed as the solution has already been applied]
(The sidebar is the div classed sideright, and contains a module titled Archiv)
Thank you in advance
Change the div.content css to:
div.content {
display: inline;
float: left;
}
You're using float, but then setting the position to relative. You should remove the relative part of your css for the siderright and it should fix the issue
Edit: even better you should change the position to absolute.
Set your container div to position:relative and then position:absolute your sidebar in relation to that.
.cframe {
display: table;
vertical-align: top;
position: relative;
}
.sideright {
width: 200px;
position: absolute;
top: 320px;
right: 0;
}
I didn't test the answers above but I take their word that they worked. However, your question caught my eye, because I thought you were looking for a browser hack.
There are ways that you can tell an element to behave differently on a specific browser. This happens sometimes across browsers and the best way is to hack each individual browser and give them specific instructions. For chrome, of course you'll have to use a webkit.
This would be an easy example of the syntax to follow:
<p>TEST</p>
p {color:green;}
#media screen and (-webkit-min-device-pixel-ratio:0) {
p {color:red;}
}
Try the DEMO in several browsers and notice how only chrome will display it in red
my question is more or less self-explanatory, I am trying to find a standard dynamic way to centralize an element in the y-axis, much like the:
margin: auto;
For the x-axis. Any ideas?
I am talking about the following piece of code, empty page, align one image in the center.
<div id="main" style="display: block;">
<img style="margin: auto; display: block;"
src="http://www.example.com/img.jpg" />
</div>
Any help will be appreciated! :)
Just give up and use tables on this one, with vertical-align: middle. You can get away with just a single-row, single-cell table without feeling too guilty (I sleep like a baby about it). It's not the most semantic thing in the world, but what would you rather maintain, a tiny one celled table, or figuring out the exact height and doing absolute positioning with negative margins?
If you know the height of the element that you're trying to center, you can do this:
img {
display: block;
height: 500px;
position: absolute;
top: 50%;
margin-top: -250px; /* 50% of your actual height */
}
I know only one way for that:
#mydiv {
position: fixed;
top: 50%;
left: 50%;
width: 100px;
height: 100px;
margin-top: -50px;
margin-left: -50px;
}
This is for x and y axis - but width/height and margins have to be changed for every element. I hate it :-)
Additionally you get problems if the element is larger than the browser-window.
The best known method is to use absolute positioning. You set the top amount to 50% and then set a margin top of minus half of the element.
#main {
position: relative;
}
#main img {
position: absolute;
top: 50%;
margin-top: -(half your image height)px;
}
Here is a variation using vertical-align
http://jsfiddle.net/audetwebdesign/r46aS/
It has a down side in that you need to specify a value for line-height that will also define the height of the containing element that acts like the viewport (outlined in blue).
Note: You may be able to get around the window height issue by setting a height to the body or html element (100%) but you would need to try it out (see 3rd reference).
However, the good thing is that you don't have to do some math based on the dimensions of the image.
Here are some references related to vertical alignment:
http://css-tricks.com/what-is-vertical-align
http://blog.themeforest.net/tutorials/vertical-centering-with-css
http://www.jakpsatweb.cz/css/css-vertical-center-solution.html
and sometimes I have to remember the basics so I reread:
http://www.w3.org/TR/CSS21/visudet.html
This may not solve OP's problem, but may be useful in other contexts.
Using #menu img { vertical-align: middle; } in my style sheet works great for the latest versions of FireFox, Opera, Safari and Chrome, but not in IE9. I have to manually add style="vertical-align: middle" to every line of img code. For example:
<li><a href="../us-hosts.php">
<img src="../images/us-button.png" width="30" height="30"
alt="US Hosts" style="vertical-align: middle;"/> US Hosts</a>
</li>
Try this css:
margin-top:auto;
margin-bottom:auto;
display:block;