I have spent countless hours yesterday and today to figure out how to do this. I cant believe CSS doesn't have an easy way to handle this.
Essentially, I have some text within a span class="name" whose length is not fixed. In certain instances, it can spill over to the next line. How do I vertically align this within my container.
More specifically, how do I vertically align "ABC Father And Sons Company LLC" within my container?
http://jsfiddle.net/D3L8S/
<div class="container">
<span class="name">ABC Father And Sons Company LLC </span>
Address
Hours
More
</div>
css classes
// CSS
.container {
background: #DDEBF0;
padding: 11px;
border: 1px solid #D2D2D2;
width: 380px;
margin-bottom: 10px;
height:18px;
line-height:18px;
display:inline-block;
}
.name {
width:200px;
float:left;
}
.addr, .hours, .more {
width:60px;
float:left;
}
If I add a negative top margin to "name" (margin-top:-8px), I can achieve this but it obviously messes up rendering for XYZ Company LLC
http://jsfiddle.net/FM4dA/
The solution should ideally be Cross-browser compatible (atleast ie8 should support it)
EDIT - I forgot to mention initially that my container width is fixed and cannot be changed.
Here is one way of doing it using inline blocks:
.container {
background: #DDEBF0;
padding: 11px;
border: 1px solid #D2D2D2;
width: 380px;
height: 50px;
line-height: 50px;
margin-bottom: 10px;
display:inline-block;
}
.name {
width:200px;
display: inline-block;
vertical-align: middle;
line-height: 1;
}
.addr, .hours, .more {
display: inline-block;
vertical-align: middle;
line-height: 1;
}
First, make sure to leave enough vertical space for multi-line names, so on .container,
I used height: 50px and line-height: 50px.
However, you need to reset the line-height: 1 (or some suitable value) on the child elements otherwise the interline spacing will not be attractive.
Then, instead of floats, use display: inline-block and vertical-align: middle on the
child elements (.name, .addr, .hours, .more).
See demo at: http://jsfiddle.net/audetwebdesign/Wp84v/
Note: You may not need to specify the width on .addr, .hours, .more, so I let the
widths take on the shrink-to-fit value.
One way to vertically align div's contents is to use the vertical-align css property. But it works only on display:table-cell elements. So, wrap your container into a display:table div, and change the container display to display:table-cell.
Like this: http://jsfiddle.net/D3L8S/2/
Try this, It might help somebody
.name {
width:200px;
float:left;
margin-top:-8px;
word-wrap:break-word;
text-align: center;
}
DEMO
When you want to vertically center multiple lines, put the text into an inline block then pretend that the inline-block was a single line of text.
.container {
background: #DDEBF0;
padding: 11px;
border: 1px solid #D2D2D2;
width: 380px;
margin-bottom: 10px;
height: 18px;
line-height: 18px
display:inline-block;
}
.name {
width:200px;
float:left;
margin-top:-8px;
display: inline-block;
vertical-align: middle;
line-height: 14px;
}
NOTE:
Why you should add the line-height property ?
If you add height to an element , where exactly does the text inside of it lie? That is, if you have a block of text that is font-size: 10px (a theoretical height:10px) inside a container that is 60px where exactly is the text going to end up? Most surely at the top of the container, because the text can only position itself where the text flows, inside a height:10px space. But you can overcome that by using a line-height value the same height as the container, this way the text will take in the vertical-align property and align itself properly.
Related
I am trying to get a line over my title that lines up evenly with lines before and after my `sub-title
I looked at two references:
Line before and after title over image
CSS technique for a horizontal line with words in the middle
These helped me get started but I am not sure how to get the top line even with the before and after lines without wrapping despite the length of the title or subtitle.
<div class="title">
<h1>Testingtesting</h1>
</div>
<div class="sub-title">
<h1>Testing</h1>
</div>
<style>
#import url(http://fonts.googleapis.com/css?family=Open+Sans:300);
h1 {
width: 20%;
margin: .7em auto;
overflow: hidden;
text-align: center;
font-weight:300;
color: #000;
}
h1:before, h1:after {
content: "";
display: inline-block;
width: 50%;
margin: 0 .1em 0 -55%;
vertical-align: middle;
border-bottom: 1px solid;
}
h1:after {
margin: 0 -55% 0 .1em;
}
span {
display: inline-block;
vertical-align: middle;
}
.title h1 {
border-top: 1px solid black
}
.title h1:before, .title h1:after {
border-bottom: 0px solid;
}
</style>
You should use white-space: wrap; it should work after using it as you have set width on the element on which you are setting this.
For example,
}
.title h1:after {
content:"\A";
white-space: pre;
}
Explanation
In CSS :after is used to generate some content known as a pseudo-element. The "\A" is interpreted as a line break provided that the white space is preserved, hence you need to set white-space: pre. Finally, the element has to be inline, hence display: inline.
I believe I was able to accomplish what you want with the use of flexbox. TL;DR: see snippet below.
First, I nested div.sub-title within div.title in the HTML.
Then, I turned the div.title into a flex container with display: flex, and set the flow direction to column. Adding align-items: center centers the elements within the container.
Next, I targeted the first h1 element, adding a border-top and border-bottom. You can make it however thick you like—I put 4px. If you want to add or reduce the spacing between the borders and the title, adjust the padding.
I then targeted the div.sub-title container. I gave it a position of relative and then offset its position vertically with top: -45px. You may want to adjust this value to get it centered the way you want it. I applied a zero line-height to remove the default value which is pretty tall on a heading. To adjust the spacing between the sub-title and the line on either side, add padding to div.sub-title—I used 20px. Lastly, add a background color that matches your page's background.
While this works, it'll largely depend on how much pre-defined values you're able to use (like padding and background-color).
Another thing to note is when the screen width gets too small, and the subtitle wraps, it'll look really ugly. This is due to the line-height being set to zero. To fix, you can set a min-width on div.title to prevent the entire container from going below a certain width or reset the line-height in div.sub-title at a certain breakpoint with a media query.
.title {
display: flex;
flex-flow: column nowrap;
align-items: center;
min-width: 350px;
}
.title > h1 {
display: inline;
padding: 30px 0;
border-top: 4px solid black;
border-bottom: 4px solid black;
text-align: center;
}
.sub-title {
position: relative;
top: -45px;
/* reset this w/ a media query when screen size gets too small */
line-height: 0px;
padding: 0 20px;
background-color: #fff;
}
<body>
<div class="title">
<h1>Tomorrow Or Something Longer</h1>
<div class="sub-title">
<h1>Today or something</h1>
</div>
</div>
</body>
very common question I know, but I'm still struggling having read similar questions.
I have two divs (containing a variable height text box paragraph and a fixed height image) within a container div, as follows:
<div class="error-row row">
<div class="error-value-col">
<p class="error-value">{{error.message}}</p>
</div>
<a class="cross-link">
<img class="cross" src="/assets/cross.png" alt="close">
</a>
</div>
The accompanying LESS file is:
.error-row {
border: 1px solid #po-yellow;
border-width: 0px 1px 1px 1px;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
position: relative;
margin: 0px;
.error-value-col {
float:left;
vertical-align: middle;
display: inline-block;
width: calc(~'100% - 70px');
.error-value {
font-size: 10px;
padding: 5px;
p {
margin-bottom: 0px;
}
}
}
.cross-link {
padding: 0px;
float: right;
vertical-align: middle;
display: inline-block;
height: 70px;
img.cross {
margin: auto;
width: 70px;
height: 70px;
padding: 28.5px 27.5px 26.5px 27.5px;
color: black;
}
}
}
I've tried several different combinations of settings but none seem to work. I want whatever the element with the smallest height is (out of the image and text box) to centre alongside the taller element.
Thanks all.
EDIT: Clarification...I want the error-value-col and cross-link to be centred on the error-row container. This will of course be sized to the largest element out of the two, which could be either.
I changed approach and use display:table and display:table-cell to obtain desired behaviour. Look at this updated jsFiddle to see if it's acceptable for you (converted LESS in CSS there).
Apart design rules, relevant new ones to LESS code are the following:
.error-row {
...
display:table;
width:100%;
.error-value-col {
...
display:table-cell;
vertical-align:middle;
.error-value {
...
p {
...
}
}
}
.cross-link {
...
display:table-cell;
width:70px;
vertical-align:middle;
img.cross {
...
}
}
}
Please refer to jsFiddle to see all differences including erasing of floating.
ALTERNATIVES:
Vertical aligning is (strangely) an hard topic in CSS, at least if
you don't want to use relatively new Flexbox model.
Generally a very common method is to absolute positioning inner DIV
with top:50% but due to fact that reference point is top-left
corner, then you have to push up it of "half of its height" with a
negative margin-top. This requires to have a fixed height of inner
DIV, in order to set this negative margin to half of it.
I have been searching for an answer for this for days now and no solution seems to be the correct one for my needs. Please help!
I have two divs for which I want to fill 100% width of the browser, and have more of these which will stack to fill the height. I want the text in each of these (which is being generated from javascript ) to be vertically aligned.
I have also tried using display:table-cell and it works great in all ways, however I do not have the ability to set the cell width as a fixed %, and I need to add html markup which seems to limit me in using certain media queries later on.
How can I vertically align text using inline-block?
Im having trouble making a fiddle but this is close: http://jsfiddle.net/z4bj14op/
Here is my CSS
html, body {
margin: 0;
padding: 0;
height: 100%;
overflow-y: hidden;
font-family: helvetica;
}
#status {
width: 100%;
font-size: 0;
}
#line0, #status0 {
display: inline-block;
width: 50%;
vertical-align: middle;
height: 10%;
}
h2 {
font-size: 18px;
}
#line0 {
background-color: #B36305;
color: white;
}
#status0 {
background-color: black;
color: white;
}
And the HTML
<div id ="status">
<div id="line0"></div>
<div id="status0"></div>
</div>
There is an article from Steven Bradley 6 Methods For Vertical Centering With CSS: http://www.vanseodesign.com/css/vertical-centering/
Which solution would be the best depends on your requirements. I think the Absolute Positioning and Negative Margin way could be the solution you need, as your container have a defined height.
When using display:inline-block;vertical-align:middle the element is only vertically centered to the other inline-elements of the current row.
is this what you want ?
JSfiddle Example
If you want both of the divs to be 100% in their width that impossible ! otherwise the rest of the div will hidden by the other one
clarify more what's needed ..
<div id ="status">
<div id="line0"><h2>Bakerloo</h2></div>
<div id="status0"><h2>Good Service</h2></div>
</div>
css code:
#line0{
background:pink;
width:50%;
display: inline-block;
}
#status0{
background:red;
width:49%;
display: inline-block;
}
Why are you using display: inline-block? must you use this way? try to put float: left instead display: inline-block inside block #line0,#status0 and after you can work with text-something else
You Can try this
#line0{
background:pink;
width:50%;
display: inline-block;
float:left;/*added*/
}
#status0{
background:red;
width:50%;
display: inline-block;
}
DEMO
I have a div and I want to align in the center of that div multiple images. All of the images have the same height and width of 16px. The problem is that I can either center them and have the extra space below but when I use the display:block to remove it, they are aligned to the left again. Here's my code:
div which I want to contain the images:
.cell{
position: relative;
float: left;
width: 300px;
min-height: 22px;
border-bottom: 1px solid #000;
border-right: 1px solid #000;
line-height: 22px;
font-family: Arial, Verdana;
font-size: 12px;
color: #000;
text-decoration: none;
text-align: center;
margin-bottom: 2px;
margin-right: 2px;
}
The above class has the properties needed in general.
So I want to create a class for the img elements so that they can be aligned one next to each other and all together aligned horizontally.
Any working suggestions?! :)
Floating a block level item will push it to the left or right. "display:inline-block" on the IMG. And remove the float and position statements. Then "text-align:center" for the container div.
http://jsfiddle.net/B6Jsy/
I used a div as a fake img but it should work the same.
<div class="Image">FIRST</div>
<div class="Image">SECOND</div>
.ImageHolder{
text-align:center;
}
.Image{
display:inline-block;
}
Why is the text in this example: http://jsfiddle.net/7EYZe/ not in the vertical center?
How can I middle the text?
EDIT:
Now I have two or more lines of text:
http://jsfiddle.net/7EYZe/12/
How can I display this properly?
The following css will center text in a div by using padding instead of height:
.centerText
{
padding: 90px 0;
font-size: 18px;
border:solid 1px #000;
}
That's an incorrect use of vertical-align. It doesn't know what object to vertically align itself to.
Here is one dynamic, table-less solution: http://jsfiddle.net/imoda/7EYZe/14/
<style type="text/css">
div {
height:200px;
width:200px;
border:solid 1px black;
}
.aligner {
height: 100%;
width: 0;
display: inline-block;
vertical-align: middle;
}
.align {
display: inline-block;
vertical-align: middle;
}
</style>
<div>
<span class="aligner"></span>
<span class="align">blabla</span>
</div>
Add text-align: center; and display: table-cell; to center it in middle of the box.
div {
height:200px;
width:200px;
border:solid 1px black;
text-align: center;
vertical-align:middle;
display: table-cell;
}
The div is vertically aligned within whatever surrounds it. That doesn't affect what's inside. Make it smaller, in fact remove the width, and put it inside something bigger.
The thing is, vertical-align was mainly designed for specifying the behaviour of table-cells. Although the name suggests that any content shall be aligned in the middle, it simply does not.
You can find a very good article here about what vertical-align really is and how to achieve your intended purpose - aligning the text vertically inside your div.
Use line-height:200px, e.g.
div {
border:solid 1px black;
height:200px;
line-height:200px;
width:200px;
}
Also, in your example, you won't need vertical-align:middle. That style means that the div will be vertically aligned to its parent element. It doesn't mean the text inside will be vertically aligned.
This is way too much of a pain to do with a div. Use a table cell instead:
html: <table><tr><td>My Text</td></tr></table>
css: td { vertical-align: middle; }