Vertically align contents of a button other than center - html

Usually people try to figure out how to vertically center stuff, I want to remove an instance of centered content and align and I'm stuck.
The content of the button (that is placed in a list in a table cell) is vertically centered by default. How can I remove this? How to align the contents of the <button> vertically to the top?
<table>
<tbody>
<td>
<ul>
<li>
<button>
<div>Content</div>
I have an example on jsFiddle.
button {
display: block;
position: relative;
background-color: pink;
width: 100%;
min-height: 200px;
}
<button>
<div>why?</div>
<div>are these centered vertically?</div>
<div>And how to remove it?</div>
</button>

Why the contents are vertically centered?
There's no specific reason. This is the way UAs handle the position of value/content of buttons (including <button>, <input type="button">)1.
How to remove vertical centering?
Well, there's a way to achieve that. First, a little background is needed.
But before that, you should note that <div> elements are supposed to be used where flow contents are expected. This means that they are NOT allowed to be placed inside <button> elements.
As per HTML5 spec (Which is at PR state right now):
Content model for element button:
Phrasing content, but there must be no interactive content descendant.
Therefore, a valid HTML could be like this:
<button>
why? <br>
are these centered vertically? <br>
And how to remove it?
</button>
Background
In an inline flow, inline-level elements (inline, inline-block) can be aligned vertically inside the parent by vertical-align property. Using that with a value other than baseline makes inline-level elements position somewhere other than the baseline of the parent (which is the default place).
The key point is that taller elements would affect the line box / baseline.
The Solution
First, in order to handle the position of the lines, we need to wrap them by a wrapper element like <span> as follows:
<button>
<span> <!-- Added wrapper -->
why? <br>
are these centered vertically? <br>
And how to remove it?
</span>
</button>
In cases that the parent - the <button> in this case - has an explicit height, by any chance if we could have a child element having the exact same height of the parent, we would be able to expand the height of the line box and surprisingly make our desired in-flow child - the nested <span> in this case - be aligned to the top vertically by vertical-align: top; declaration.
10.8 Line height calculations: 'vertical-align' property
This property affects the vertical positioning inside a line box of
the boxes generated by an inline-level element.
top
Align the top of the aligned subtree with the top of the line box.
EXAMPLE HERE
button { width: 100%; height: 200px; }
button > span {
display: inline-block;
vertical-align: top;
}
button:after {
content: "";
display: inline-block;
vertical-align: top;
height: 100%;
}
Last bot not least, if you'd like to use min-height rather than height for the button, you should use min-height: inherit; for the pseudo-element as well.
EXAMPLE HERE.
1 Chrome and Firefox also display the value of text inputs vertically at the middle while IE8 doesn't for instance.

Bootstrap adds padding above and below the button content (6 pixels). You can alter the padding amount with: button{padding:0px;} or button{padding-top:x; padding-bottom:y;} where x and y are whatever value you choose.
If you want to alter that button only give the button id="table" or something like that and then do: button#table{padding:0px;}
If you can avoid using vertical align you should as not all browsers support it.

Related

Why is the text in a button always centered vertically?

I want to style a div exactly like a button. I noticed that when I give the button a specific height, the text is always centered vertically.
So far i tried digging through the Chromium user agent stylesheets but was not successful. -webkit-appereance: button also did not do the trick.
Here is a demo of the issue: https://codepen.io/franzskuffka/pen/QzqKQx. Note that the inline-block styling gives makes sure the text is aligned vertically - the bounding box is still weird.
Which property makes the text centered vertically without any additional wrappers? What is going on here?
TL;DR: It is not possible to recreate the layout created by a <button> element using CSS. Or at least it is hidden really well.
I tested this by changing the display value to flex on a <button> and it affected the vertical alignment. Other values like display:block did not have an effect. It seems that there is no css value for this, it just is the default behavior and there is no way to do it for a div.
Like you, I was looking for an answer to this question. I was trying to find css property which centers vertically content in button. When I almost gave up I decided to leaf through html specification and this is what I found:
If the element is an input element, or if it is a button element and
its computed value for 'display' is not 'inline-grid', 'grid',
'inline-flex', or 'flex', then the element's box has a child anonymous
button content box with the following behaviors:
The box is a block-level block container that establishes a new
block formatting context (i.e., 'display' is 'flow-root').
If the box does not overflow in the horizontal axis, then it is
centered horizontally.
If the box does not overflow in the vertical axis, then it is
centered vertically. Otherwise, there is no anonymous button content box.
https://html.spec.whatwg.org/multipage/rendering.html#button-layout
If your button doesn't have a fixed height, you can add padding to the div to center the text vertically. Add text-align: center; to center your text horizontally.
.btn {
background-color: #000;
color: #fff;
padding: 10px;
text-align: center;
}
<div class="btn">Hello!</div>
For a button with a fixed height, you may have to have a child element.
.parent {
background-color: #000;
color: #fff;
height: 100px;
text-align: center;
width: 100px;
}
.child {
top: 50%;
transform: translateY(-50%);
}
<div class="parent">
<div class="child">Hello!</div>
</div>
There are several other methods, but these are the ones I commonly resort to. CSS-Tricks has a complete guide on centering in CSS if you'd like to try out more methods: https://css-tricks.com/centering-css-complete-guide/.

Why does text-align center headers?

Why does text-align: center headers?
Headers are block elements h1,h2,etc. Why is it that text-align centers headers even though the documentation specifically says it does not: Docs on text-align
This property describes how inline-level content of a block container
is aligned.
I'm a little confused as to why it wont center a block element like a div, but willing to center a header. Could it potentially be because text inside a header is inline, but the actual header itself is a block element?
http://codepen.io/stephenhuh/pen/KrkLZG - codepen on this phenomenon.
* {
text-align: center;
}
.box {
background-color: blue;
width: 150px;
height: 150px;
}
From CSS 2:
Any text that is directly contained inside a block container element (not inside an inline element) must be treated as an anonymous inline element.
Like everyone else has already explained, it is centering the text content inside the header element. I'd just like to add that you can easily test this by adding a border or background to elements. If you do this, you'll notice that the header will span the entire width of its container by being a block element, and the text will only be centered inside that block.
(Alternatively, you could use an inspector to show the actual space an element is occupying)
The property text-align affects specific children of the parent that the property was assigned; namely inline type children. Text is inline, as well as spans and inputs unless otherwise overridden by CSS. If you need to center a block level element (horizontally) use margin:0 auto;.

Centering a form, but maintaining alignment of its contents

I have a three-column page. Each column is a div with the following styles:
.Row1 {
text-align:center;
display:inline-block;
vertical-align:top;
padding:0.5%;
width:31.5%;
}
The HTML is as follows:
<div class="Row1">
<h2>Header</h2>
<br />
<form>
Form stuff goes here
</form>
</div>
My form consists of nothing more than a text field, a few radio buttons, and a submit button. Problem is, putting the form into the above code will give me a centered form, with the text field, radio buttons, and submit button also aligned in the center.
What I am trying to do is to just center the form itself (as a container), but keep everything aligned to the left.
I have tried wrapping the form in a div that is text-aligned centrally, and the form style set to left align, but that didnt work. The auto margin thing didn't work, either, whether it was on the wrapping div, or on the form, without the wrapping div (that is, an extra div. the Row1 div always remains).
EDIT: http://jsfiddle.net/pJwqe/
text-align is not a property to 'align' divs or forms; instead, as it says, it aligns text.
If you want to center a block-level element, you'll have to use margin. The default way to center a single element with margin is to set it , for example for a top-level container, to margin: 0px auto 0px;.
If you want a lay-out with 3 columns, I'd rather think you'd want something like this.
You can style the margins of your divs by setting margin-left or margin-right, then style the first/last element with advanced selectors (so you don't have a margin-left for your first element, or a margin-right for your last).
As you can see, the forms are now centered, but their content is not. (You need to give your forms a width, else they will fill the containing block by default if they have content).
NB: It might be relevant in the rest of your code, but in this test-case vertical-align does nothing.
Hope this fiddle link will work for you. I have done the following changes in your css
.midAlign form {
border: 1px solid #C2C3C0;
margin: 0 auto;
padding: 10px;
width: 155px;
}

Text-align does not apply to images

I just wrote the following code
<img src="http://www.lorempixel.com/100/100"><img src="http://www.lorempixel.com/100/150" id="test">
#test {
text-align: center;
}
But the image is not centering. I also used text-align: right which did not work either. I can use float and margin-left but I'm curious why its not working with text-align.
Have a look at text-align css property as described on w3.org website. It says that this property applies to block containers.
Now, the <img> tag itself is not a container (it cannot contain any thing) hence the text-align property does not work as expected. To make an image center-align, there are various ways; the simplest of them is to specify text-align: center on its parent element.
This property specifies how the inline content of a block is aligned,
when the sum of the widths of the inline boxes is less than the width
of the line box.
Try putting the img in a div with inline-block specified and the first image as the background image of the div.
something like:
<div style="display: block; text-align: center; background-image:url([your_first_image]);">
<img src="[your_second_image]"/>
</div>
However, this probably will not work on an image, you need to use float, padding or something of that nature.
img {
display: block;
margin-left: auto;
margin-right: auto;
}
It should work! It worked for me :D
text-align is used for aligning the text within an element. An img element has no text inside of it to center, so it does nothing. float, which floats the element within its parent, is probably what you want here.
Not the best practice text-align to align images.
"The tricky thing about the text-align property is that you can only align text with it - you can't use it to move block-level elements like images. Some browsers will align images or tables with this property, but it's not reliable, as you've found." --Jennifer Kyrnin, About.com
You can use the deprecated img attribute align="center", Although you won't use. This way tags and style are mixed, and, to worsen, there are vertical and horizontal spaces around the full image.
<img src="http://www.lorempixel.com/100/150" align="center"> <-- Wrong way
The best way to solve this is using CSS. Setting the image as div's background then the div's space will be your image's space and you can use margins to put it in place. You can try to use one of these others techniques
CSS background-image Technique:
background:url('path_to_img') center center no-repeat; /* div center */
background:url('path_to_img') center 0 no-repeat; /* div horizontal center */
background:url('path_to_img') 0 center no-repeat; /* div vertical center */
I try this and it works fine :
In the CSS:
.centreimage {
text-align: center;
}
In the HTML:
<p class="centreimage">
<img src="Images/blababla.png">
</p>
Another way -- you can wrap it around a table. see below.
We had to do it this way in a stylesheet.
<html>
<table border="0" width="530" >
<td align="center" valign="center">
<img src="http://www.lorempixel.com/100/150" id="test">
</img>
</td>
</table>
</html>
Consider learning about the CSS display property, a very important CSS property in my opinion, at least when dealing with positioning and alignment. The property is set to different values on different elements by default. Assuming the position property is set to the static value, block and inline take up the entire parent element's width. block will be on its own line while inline shares the line with other elements.
Elements like p tags and h1s are block level elements. Elements like span tags and ems are inline elements. Images however are neither!
Images have a default display value of inline-block. This means it has the characteristics of inline and block elements - You can set the width and height (like block level elements), it is on the same line as other elements (like inline level elements), and the container is the width and padding - nothing else.
The CSS rule text-align: center; centers the element in its container. This means for p elements it will be fine because the display is set to block. For images, however, you cannot center it (so nothing will happen) unless you put it in a div (parent element container) because, assuming the width is set to 100%, there is nothing to center it in, nothing to be aligned with. Consider the following example:
body * {
border: 1px solid black;
text-align: center;
}
<body>
<p> This is a <span> !!Span element containing!! paragraph !!Span element containing!!</span>about lorem ipsum, the infamous place holder text. Lorem ipsum is supposedly Latin, but not really. That's all. </p>
<img width = '200' src="https://i.stack.imgur.com/zZTPs.png">
<p> The display of p is block, span inline, img inline-block. That's why the image's border doesn't stretch and the others do (you may not notice it but they do)</p>
</body>
A good workaround is setting the display to block. This will make ti stretch so there is something to center it in. As soon as there is something that acts as a parent container, ether it be changing the display (the border is what you are aligning it on) or enclosing it in a div (the div is what you are aligning it on) the aligning will then work.
because it is "text"-align.
the property is designed to work a certain way and given a certain name.
Interestingly, if a the property is applied to a container that has image+text then the alignment works for text as well as image.
.one{
text-align: center}
<div class="one">
<p>hello pal</p>
<img src="https://cn.i.cdn.ti-platform.com/content/22/showpage/regular-show/za/regularshow-200x200.png">
</div>

How can I make my DIV just the size of the text it encloses

I have this code:
<div id="one">
<div id="two">my text here</div>
</div>
I have styled the div with id=two and put a box around it. The problem is that it doesn't enclose the text but instead expands to the width of the outer DIV. Is there a way I can make it just size to match the text without specifying width?
You can either
#two {
display: inline; /* or 'inline-block' */
}
Or:
#two {
float: left; /* or right */
}
display: inline; stops the div being displayed as a block-level element, causing it to collapse (for want of a better word) to the size of its contents. If you use the alternative display: inline-block then the div retains its ability to have a defined width and height, which may be required for your layout. However it's worth noting that Internet Explorer 6 and 7 only accepts display: inline-block for those elements that are 'naturally inline.'
float has much the same effect; but using float might/will obviously affect the layout of the page, and may need to be cleared by subsequent elements.
display:inline-block;
This way you keep the block behaviour of your div.