I have a use case whereby I want to draw rectangles in CSS. I need them to look like this:
I've managed to get the smaller and taller boxes drawn but can't work out how to draw those that drop below the line. Here's a fiddle
Heres' my HTML:
<div class="word">
<p class="letter taller"></p>
<p class="letter"></p>
<p class="letter"></p>
<p class="letter hanging"></p>
<p class="letter"></p>
<p class="letter taller"></p>
<p class="letter"></p>
</div>
Here's my CSS so far:
p {
display: inline-block;
}
.letter {
padding 1.618em;
border-width: 1px;
border-style: solid;
width: 2em;
height: 2em;
}
.taller {
height: 4em;
}
.hanging {
/* not sure what to implement here */
}
Using margins may affect other elements, especially if you plan on including other content on your page. (See this) I'd recommend using position: relative combined with top: 2em. What that does is it pushes the element down 2em, relative to the original position of the element.
.hanging {
height: 4em;
position: relative;
top: 2em;
}
http://jsfiddle.net/WtuyL/6/
(On an unrelated note... here's a little bonus if you want to fully imitate the image and remove whitespace. You'll net to set a manual size to all <p> elements though.)
The simplest way is to use a negative margin-bottom to achieve this (you don't need to use positioning):
CSS:
.hanging {
margin-bottom: -16px;
height:4em;
}
JSFiddle
Note: also comment the whitespace between display:inline-block elements to remove it.
Reference - see this to see more hacks how to remove the whitespace between display:inline-block elements.
Try this.
.hanging {
height:4em;
margin-bottom:-1em;
}
Related
I'm trying to teach myself some web coding, so please bare with me. At the moment, I'm creating a modal page whose modal contents have three div elements (a close button, an image, and paragraph tags). I have applied some padding on the left side of the divs in the modal content divs because I wanted the image and the paragraphs to be spaced next to each other pretty nicely. However, I want the padding to only apply to the image and the paragraphs tags, and NOT the close button.
My question is, is there a way to apply padding to only the image and paragraph tags, but NOT the close button div.
CSS
#modalPage1{
height: 100%;
width: 100%;
position:absolute;
top: 0;
background-color: rgba(255, 128, 213, 0.5);
display: flex;
justify-content: center;
align-items: center;
}
#modalPage1 > #modalContent1 {
background-color: white;
height:100%;
width: 75%;
display:flex;
align-items: center;
position:relative;
}
#close{
position: absolute;
top: 0;
right: 14px;
font-size: 50px;
transform: rotate(45deg);
padding:0%;
}
div > #modalTxt{
width: 80%;
}
#modalContent1 > div {
padding-left: 10%;
}
div > #modalImg{
width: 353px;
height: 447px;
}
HTML
<div ID= "modalPage1" class = "modalFish">
<div ID = "modalContent1" class = "modalFishContent">
<div ID="close">+</div>
<div><img ID= "modalImg" class= "modalFishImg" src="Images/Fish School.jpg"></div>
<div><p ID = "modalTxt">The inspiration behind this piece was Fall foliage. Deep red being one of my favorite colors for the fall,
I decided to use this as the background. Being that it's a dark color, it's easy to layer on different
colors that will coordinate well, while adding a pop to it. </p>
<p ID = "modalTxt">Around this time I had been making a few more "simpler" and "cute" pieces, so I wanted to being myself back
to making something a little bit more abstract. Although semi simple in design, from afar, the origami pieces
appear a bit obscure, almost reminiscent of a pile of leaves. Looking closely, we can see that the origami is
in fact fish swimming in all different directions.
</p>
</div>
</div>
</div>
The CSS code you currently have below applies the padding to every div that's inside the div with id="modalContent1". That's a problem because you can't specify what elements you want the padding to apply to; if it's a div, it gets padded. You could change the button to something that's not a div, but any other divs you add would still get padded.
#modalContent1 > div {
padding-left: 10%;
}
Instead of doing that, we can use classes instead, so only elements that belong to the class get padded. We can start by replacing the code above with the CSS below.
.padding {
padding-left: 10%;
}
This will apply the padding to every HTML element with class="padding".
Now we just have to add the classes into the HTML. You used ID="modalTxt" in your HTML twice, but IDs should only be used once, so we can replace that with class="modalTxt" instead. Make sure you replace that in your CSS too so you can keep the width customization, just change the # in div > #modalTxt to a . like this:
div > .modalTxt{
width: 80%;
}
Multiple classes can be used as long as they're separated by spaces, and having a separate class for padding lets you customize the padding on its own, and the elements' other attributes on their own. So your HTML would look like:
<div ID= "modalPage1" class = "modalFish">
<div ID = "modalContent1" class = "modalFishContent">
<div ID="close">+</div>
<div><img ID= "modalImg" class = "modalFishImg padding" src="Images/Fish School.jpg"></div>
<div><p class = "modalTxt padding">The inspiration behind this piece was Fall foliage. Deep red being one of my favorite colors for the fall,
I decided to use this as the background. Being that it's a dark color, it's easy to layer on different
colors that will coordinate well, while adding a pop to it. </p>
<p class = "modalTxt padding">Around this time I had been making a few more "simpler" and "cute" pieces, so I wanted to being myself back
to making something a little bit more abstract. Although semi simple in design, from afar, the origami pieces
appear a bit obscure, almost reminiscent of a pile of leaves. Looking closely, we can see that the origami is
in fact fish swimming in all different directions.
</p>
</div>
</div>
</div>
One last thing, you can safely remove the "modalFishTmg" class if you're not going to use it in any other elements, since you're already styling the image with an ID. Also, the classes could go in the divs where you put your <img> and <p> tags, but that would give the padding to anything that's in the div, which could be a problem if you add anything else.
To apply styling to every child div of #modalContent1 except for the div with identifier close this snippet uses the CSS :not pseudo class:
#modalContent1 > div:not(#close) {
/* set the padding as required here */
}
Just to make it obvious in this test, the background color of the relevant elements is set rather than padding:
#modalPage1 {
height: 100%;
width: 100%;
position: absolute;
top: 0;
background-color: rgba(255, 128, 213, 0.5);
display: flex;
justify-content: center;
align-items: center;
}
#modalPage1>#modalContent1 {
background-color: white;
height: 100%;
width: 75%;
display: flex;
align-items: center;
position: relative;
}
#close {
position: absolute;
top: 0;
right: 14px;
font-size: 50px;
transform: rotate(45deg);
padding: 0%;
}
div>#modalTxt {
width: 80%;
}
#modalContent1>div {
padding-left: 10%;
}
div>#modalImg {
width: 353px;
height: 447px;
}
#modalContent1>div:not(#close) {
background-color: cyan;
}
<div ID="modalPage1" class="modalFish">
<div ID="modalContent1" class="modalFishContent">
<div id="close">+</div>
<div><img ID="modalImg" class="modalFishImg" src="Images/Fish School.jpg"></div>
<div>
<p ID="modalTxt">The inspiration behind this piece was Fall foliage. Deep red being one of my favorite colors for the fall, I decided to use this as the background. Being that it's a dark color, it's easy to layer on different colors that will coordinate well, while
adding a pop to it. </p>
<p ID="modalTxt">Around this time I had been making a few more "simpler" and "cute" pieces, so I wanted to being myself back to making something a little bit more abstract. Although semi simple in design, from afar, the origami pieces appear a bit obscure, almost
reminiscent of a pile of leaves. Looking closely, we can see that the origami is in fact fish swimming in all different directions.
</p>
</div>
</div>
</div>
Note: view in full page othewise elements overlap and the effect cannot be seen correctly.
There are multiple ways to do this .
Add padding in #modalImg & #modalTxt.
Don't use 2 tags in img and p. Bring them under one div tag and apply inline CSS or a separate class or id .
I have run into and issue when styling quotes. So what I'm trying to do is pull the quotation marks down a bit relative to the text so that it lines up well. I played around with relative and absolute positioning but could not figure it out. This program will become a random quote generator and the position of the end quote has to be such that it lines up the same way relative to the text if it there is a quote that takes up several lines.
body {
background-color: rgb(44, 62, 80);
}
.quoteMachine {
margin: 100px auto 0 auto;
padding: 40px 60px;
max-width: 600px;
min-height: 225px;
border-radius: 5px;
background-color: white;
}
.theQuote {
text-align: center;
font-size: 30px;
color: rgb(44, 62, 80);
}
.quotetationMarks {
font-size: 60px;
font-weight: 600;
}
.quoteAuthor {
text-align: right;
font-size: 20px;
color: rgb(44, 62, 80);
}
.twitterButton {}
<div class="quoteMachine">
<div class="theQuote">
<blockquote><span class="quotetationMarks">“</span > They call me Mister Tiibs <span class="quotetationMarks">”<span></blockquote>
</div>
<div class="quoteAuthor">
- hello
</div>
<button class="twitterButton"></button>
<button class="newQuoteButton"></button>
</div>
Since the spans are inline elements, you could add vertical-align: middle; to .quotetationMarks and that would move them down toward the middle of the rest of the string.
Alternatively, you could add position: relative; top: 10px; if you need more precise control.
Maybe adding vertical-align: sub; to .quotetationMarks is what you are looking for?
You can also use fontawesome, that's always a good option. -> http://fontawesome.io/icon/quote-right/
Edit: While vertical-align: middle; is a very valid and elegant approach, sometimes you've got a very specific position in mind for the quotation marks. If you need to match a mockup to pixel perfection, this approach grants you the flexibility.
You might get some mileage out of using pseudo-elements to render the quotes, and relative/absolute positioning to get them "just so".
This is especially important to help position them across line breaks. (I've edited my example to force a line break, in order to illustrate the robustness of this approach.)
From MDN:
Just like pseudo-classes, pseudo-elements are added to selectors but instead of describing a special state, they allow you to style certain parts of a document. For example, the ::first-line pseudo-element targets only the first line of an element specified by the selector.
And specifically for the ::before pseudo element:
::before creates a pseudo-element that is the first child of the element matched. It is often used to add cosmetic content to an element by using the content property. This element is inline by default.
These quotes you're styling are cosmetic content, so I think that this is a great use-case for the ::before pseudo element.
I've forked your codepen here: http://codepen.io/cam5/pen/kkxpbX, but here are the relevant parts
<!-- quote HTML -->
<blockquote>
<span class="quotationMark quotationMark--left"></span >
They call me…<br /> Mister Tiibs
<span class="quotationMark quotationMark--right"></span >
</blockquote>
and the CSS:
/* quote css */
.quotationMark {
position: relative;
}
.quotationMark--left::before,
.quotationMark--right::before {
font-size: 60px;
font-weight: 600;
position: absolute;
top: -15px;
}
.quotationMark--left::before {
content:"\201C";
left: -45px;
}
.quotationMark--right::before {
content:"\201D";
right: -45px;
}
This CSS Tricks resource is great when you're trying to locate the ISO for putting a certain glyph into a CSS content rule: https://css-tricks.com/snippets/html/glyphs/
Setting the parent element, the .quotationMark to display: relative; will mean that the top, right, left values passed to the children (the pseudo-elements) of it bearing the position: absolute; property are calculated relative to their parent.
How do I make a header cover the contents and span the entire page length? When I use this css
#header {
display: inline-block;
background-color: #015367;
}
#login {
color: #b92c2c;
font-size: 1.25em;
margin-left: 18em;
position: relative;
top: 16px;
text-decoration: none;
}
#search-form {
margin-left: 0.5em;
margin-right: 15em;
position: relative;
top: 18px;
}
.lfloat {
float: left;
}
.rfloat {
float: right;
}
with this html
<body>
<div id="header">
<div id="page-nav" class="rfloat">
<a id="login" class="lfloat" href="/login">login</a>
<form id="search-form" class="rfloat" action="search.py" method="get">
<input id="searchbox" type="text" name="q" placeholder="search"/>
</form>
</div>
</div>
</body>
I get this result (in firefox)
What do I need to change to get a proper header (like stackoverflow, facebook, etc)?
Since you used float for the elements inside #header, then you only need to add this.
#header {
background-color: #015367;
overflow:hidden;
}
Before overflow:hidden
Notice the black border, the #header isn't wrapping the contents.
After overflow:hidden
Check it out : http://jsfiddle.net/AliBassam/vpRc2/
Adjust the top so that elements are positioned the way you like, position:relative; has no use here, just use floats and margins.
Add this to your CSS to zero out the margin on the body:
body {
margin: 0;
}
See DEMO.
I would also suggest you remove your position and top properties from #login and #search-form, and use margin to position them instead.
inline-block ??
#header {
float:left;
width:100%;
clear:both;
}
I suspect you are trying to just extend the header box to contain the login form.
The effect you are experiencing is due to the use of floating elements in the header tag. Floated elements are taken out of the normal flow of the document, this is why the parent element cannot detect their actual occupation of space.
There is an easy fix to this just add a overflow:hidden; to the style of header div. This would fix the problem but it is not considered to be the right way to do it. The overflow is not meant to be used in such a manner. Instead my advice to you is to use the "clearfix" method.
Here is link for the actual code: http://www.webtoolkit.info/css-clearfix.html
All you have to do is to add this code as a class to the header element.
I hope this helps :)
I'd like to have a line that starts right after my text on the same line, I've tried with the following simple code
<html><body>My Text<hr/></body></html>
It seems that <hr> is not an option because it is always on a new line and I'd like the line to start at the right of my text.
Any help ?
The <hr> has default styling that puts it on a new line. However that default styling can be over-ridden, in the same way as it can for any other element. <hr> is in essence nothing more than an empty <div> with a default border setting.
To demonstrate this, try the following:
<div>Blah blah<hr style='display:inline-block; width:100px;' />dfgdfg</div>
There are a number of ways to override the styling of <hr> to acheive your aim.
You could try using display:inline-block; along with a width setting, as I have above. The down-side of this approach is that it requires you to know the width you want, though there are ways around this - width:100%;, and the whole line in a container <div> that has overflow:hidden; might do the trick, for example:
<div style='overflow:hidden; white-space:nowrap;'>Blah blah<hr style='display:inline-block; width:100%;' /></div>
Another option would be to use float:left;. You'd need to apply this to all the elements in the line, and I dislike this option as I find that float tends to cause more problems than it solves. But try it and see if it works for you.
There are various other combinations of styles you can try - give it a go and see what works.
Using FlexBox Property this can be achieved easily.
.mytextdiv{
display:flex;
flex-direction:row;
align-items: center;
}
.mytexttitle{
flex-grow:0;
}
.divider{
flex-grow:1;
height: 1px;
background-color: #9f9f9f;
}
<div class="mytextdiv">
<div class="mytexttitle">
My Text
</div>
<div class="divider"></div>
</div>
Try this:
<html><body>My Text<hr style="float: right; width: 80%"/></body></html>
The inline CSS float: right will keep it on the same line as the text.
You'll need to adjust the width if you want it to fill the rest of the line.
Using inline or float, as far as I tested it doesn't work properly even if this was my first thought. Looking further I used the following css
hr {
bottom: 17px;
position: relative;
z-index: 1;
}
div {
background:white;
position: relative;
width: 100px;
z-index: 10;
}
html
<div>My Text</div><hr/>
Demo http://jsfiddle.net/mFEWk/
What I did, is to add position relative in both elements (to give me the advantage of z-index use). Also from the moment I had position:relative for hr I moved it from the bottom:17px. This move it above the div that contains the text. Applying z-index values and adding background:white for the div puts the text above the the line. Of course don't forget to use a width for the text, otherwise will take the whole width of the parent element.
<div style="float: left">Some text</div>
<hr style="clear: none; position: relative; top: 0.5em;">
Exactly what you want.
Try this. It works
<p style="float:left;">
Hello Text
<hr style="float:left; width: 80%"/>
</p>
You can also use this to draw a line between texts like
Hello -------------------------- Hello
The OP never specified the purpose of the line, but I wanted to share what I ended up doing when I was making an html template where the user needed a line to write on after the document was printed.
Because the hr tag defaults to its own line and defaults to being centered in the line, I decided to use a div and style it instead.
HTML
This is my text.<div class='fillLine'></div>
CSS
.fillLine {
display:inline-block;
width: 200px;
border-bottom: 1px solid black;
}
JSFiddle Demo
Style Div for Line After Text
Hope that helps anyone who had the same goal as me.
hr {
width: {so it fits on the same line as the p tag};
}
p {
float: left;
width: {enough to accomodate the hr};
}
That sort of make sense?
<p>My text</p>
<hr />
Here's one potential approach, but it has some assumptions/requirements. Your question should be edited to give more specific information about what you're building.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>Blah</title>
<style type="text/css">
body {
background-color : white;
font-family : Arial;
font-size : 16px;
}
.wrap {
background: transparent url(px.png) repeat-x 0px 85%;
/* Different fonts or text sizes may require tweaking of that offset.
px.png is a one-pixel(though can be thicker if needed) image in whatever color you want the line */
}
.inner {
background-color : white;
/* Should match the background of whatever it's sitting over.
Obviously this requires a solid background. */
}
</style>
</head>
<body>
<div class="wrap"><span class="inner">Here is some text</span></div>
</body>
</html>
I used the following technique:
Give the container div a background-image with a horizontal line.
Put an element (like <h3>) in the container div (I have it on the right so float: right; )
Use the following css:
.line-container {
width: 550px;
height: 40px;
margin-top: 10px;
background-image: url("/images/horizontal_line.png");
}
.line-container h3 {
padding-left: 10px;
float: right;
background-color: white;
}
Below code did the job for me
HTML File:
----------
<p class="section-header">Details</p><hr>
CSS File:
----------
.section-header{
float: left;
font-weight: bold
}
hr{
float: left;
width: 80%;
}
INLINE:
-------
<p style="float: left;font-weight: bold">Details</p><hr style="float: left;width: 80%;">
Ok, I had a simple layout problem a week or two ago. Namely sections of a page needed a header:
+---------------------------------------------------------+
| Title Button |
+---------------------------------------------------------+
Pretty simple stuff. Thing is table hatred seems to have taken over in the Web world, which I was reminded of when I asked Why use definition lists (DL,DD,DT) tags for HTML forms instead of tables? Now the general topic of tables vs divs/CSS has previously been discussed, for example:
DIV vs Table; and
Tables instead of DIVs.
So this isn't intended to be a general discussion about CSS vs tables for layout. This is simply the solution to one problem. I tried various solutions to the above using CSS including:
Float right for the button or a div containing the button;
Position relative for the button; and
Position relative+absolute.
None of these solutions were satisfactory for different reasons. For example the relative positioning resulted in a z-index issue where my dropdown menu appeared under the content.
So I ended up going back to:
<style type="text/css">
.group-header { background-color: yellow; width: 100%; }
.group-header td { padding: 8px; }
.group-title { text-align: left; font-weight: bold; }
.group-buttons { text-align: right; }
</style>
<table class="group-header">
<tr>
<td class="group-title">Title</td>
<td class="group-buttons"><input type="button" name="Button"></td>
</tr>
</table>
And it works perfectly. It's simple, as backward compatibile as it gets (that'll work probably even on IE5) and it just works. No messing about with positioning or floats.
So can anyone do the equivalent without tables?
The requirements are:
Backwards compatible: to FF2 and IE6;
Reasonably consistent: across different browsers;
Vertically centered: the button and title are of different heights; and
Flexible: allow reasonably precise control over positioning (padding and/or margin) and styling.
On a side note, I came across a couple of interesting articles today:
Why CSS should not be used for layout; and
Tables vs CSS: CSS Trolls begone
EDIT: Let me elaborate on the float issue. This sort of works:
<html>
<head>
<title>Layout</title>
<style type="text/css">
.group-header, .group-content { width: 500px; margin: 0 auto; }
.group-header { border: 1px solid red; background: yellow; overflow: hidden; }
.group-content { border: 1px solid black; background: #DDD; }
.group-title { float: left; padding: 8px; }
.group-buttons { float: right; padding: 8px; }
</style>
</head>
<body>
<div class="group-header">
<div class="group-title">This is my title</div>
<div class="group-buttons"><input type="button" value="Collapse"></div>
</div>
<div class="group-content">
<p>And it works perfectly. It's simple, as backward compatibile as it gets (that'll work probably even on IE5) and it just works. No messing about with positioning or floats.</p>
<p>So can anyone do the equivalent without tables that is backwards compatible to at least FF2 and IE6?</p>
<p>On a side note, I came across a couple of interesting articles today:</p>
</div>
</body>
</html>
Thanks to Ant P for the overflow: hidden part (still don't get why though). Here's where the problem comes in. Say I want the title and button to be vertically centered. This is problematic because the elements are of different height. Compare this to:
<html>
<head>
<title>Layout</title>
<style type="text/css">
.group-header, .group-content { width: 500px; margin: 0 auto; }
.group-header { border: 1px solid red; background: yellow; overflow: hidden; }
.group-content { border: 1px solid black; background: #DDD; }
.group-header td { vertical-align: middle; }
.group-title { padding: 8px; }
.group-buttons { text-align: right; }
</style>
</head>
<body>
<table class="group-header">
<tr>
<td class="group-title">This is my title</td>
<td class="group-buttons"><input type="button" value="Collapse"></td>
</tr>
</table>
<div class="group-content">
<p>And it works perfectly. It's simple, as backward compatibile as it gets (that'll work probably even on IE5) and it just works. No messing about with positioning or floats.</p>
<p>So can anyone do the equivalent without tables that is backwards compatible to at least FF2 and IE6?</p>
<p>On a side note, I came across a couple of interesting articles today:</p>
</div>
</body>
</html>
which works perfectly.
There is nothing wrong with using the tools that are available to you to do the job quickly and correctly.
In this case a table worked perfectly.
I personally would have used a table for this.
I think nested tables should be avoided, things can get messy.
Just float left and right and set to clear both and you're done. No need for tables.
Edit: I know that I got a lot of upvotes for this, and I believed I was right. But there are cases where you simply need to have tables. You can try doing everything with CSS and it will work in modern browsers, but if you wish to support older ones... Not to repeat myself, here the related stack overflow thread and rant on my blog.
Edit2: Since older browsers are not that interesting anymore, I'm using Twitter bootstrap for new projects. It's great for most layout needs and does using CSS.
Float title left, float button right, and (here's the part I never knew until recently) - make the container of them both {overflow:hidden}.
That should avoid the z-index problem, anyway. If it doesn't work, and you really need the IE5 support, go ahead and use the table.
This is kind of a trick question: it looks terribly simple until you get to
Say I want the title and button to be vertically centered.
I want to state for the record that yes, vertical centring is difficult in CSS. When people post, and it seems endless on SO, "can you do X in CSS" the answer is almost always "yes" and their whinging seems unjustified. In this case, yes, that one particular thing is hard.
Someone should just edit the entire question down to "is vertical centring problematic in CSS?".
In pure CSS, a working answer will one day be to just use "display:table-cell". Unfortunately that doesn't work across current A-grade browsers, so for all that you might as well use a table if you just want to achieve the same result anyway. At least you'll be sure it works far enough into the past.
Honestly, just use a table if it's easier. It won't hurt.
If the semantics and accessibility of the table element really matter to you, there is a working draft for making your table non-semantic:
http://www.w3.org/TR/wai-aria/#presentation
I think this requires a special DTD beyond XHTML 1.1, which would just stir up the whole text/html vs application/xml debate, so let's not go there.
So, on to your unresolved CSS problem...
To vertically align two elements on their center: it can be done a few different ways, with some obtuse CSS hackery.
If you can fit within the following constraints, then there is a relatively simple way:
The height of the two elements is fixed.
The height of the container is fixed.
The elements will be narrow enough not to overlap (or can be set to a fixed width).
Then you can use absolute positioning with negative margins:
.group-header { height: 50px; position: relative; }
.group-title, .group-buttons { position: absolute; top: 50%; }
# Assuming the height of .group-title is a known 34px
.group-title { left: 0; margin-top: -17px; }
# Assuming the height of .group-buttons is a known 38px
.group-buttons { right: 0; margin-top: -19px; }
But this is pointless in most situations... If you already know the height of the elements, then you can just use floats and add enough margin to position them as needed.
Here is another method which uses the text baseline to vertically align the two columns as inline blocks. The drawback here is that you need to set fixed widths for the columns to fill out the width from the left edge. Because we need to keep the elements locked to a text baseline, we can't just use float:right for the second column. (Instead, we have to make the first column wide enough to push it over.)
<html>
<head>
<title>Layout</title>
<style type="text/css">
.group-header, .group-content { width: 500px; margin: 0 auto; }
.group-header { border: 1px solid red; background: yellow; }
.valign { display: inline-block; vertical-align: middle; }
.group-content { border: 1px solid black; background: #DDD; }
.group-title { padding: 8px; width: 384px; }
.group-buttons { padding: 8px; width: 84px; text-align: right; }
</style>
<!--[if lt IE 8]>
<style type="text/css">
.valign { display: inline; margin-top: -2px; padding-top: 1px; }
</style>
<![endif]-->
</head>
<body>
<div class="group-header">
<div class="valign">
<div class="group-title">This is my title.</div>
</div><!-- avoid whitespace between these! --><div class="valign">
<div class="group-buttons"><input type="button" value="Collapse"></div>
</div>
</div>
<div class="group-content">
<p>And it works perfectly, but mind the hacks.</p>
</div>
</body>
</html>
The HTML: We add .valign wrappers around each column. (Give them a more "semantic" name if it makes you happier.) These need to be kept without whitespace in between or else text spaces will push them apart. (I know it sucks, but that's what you get for being "pure" with the markup and separating it from the presentation layer... Ha!)
The CSS: We use vertical-align:middle to line up the blocks to the text baseline of the group-header element. The different heights of each block will stay vertically centered and push out the height of their container. The widths of the elements need to be calculated to fit the width. Here, they are 400 and 100, minus their horizontal padding.
The IE fixes: Internet Explorer only displays inline-block for natively-inline elements (e.g. span, not div). But, if we give the div hasLayout and then display it inline, it will behave just like inline-block. The margin adjustment is to fix a 1px gap at the top (try adding background colors to the .group-title to see).
I would recommend not using a table in this instance, because that is not tabular data; it's purely presentational to have the button located at the far right. This is what I'd do to duplicate your table structure (change to a different H# to suit where you are in your site's hierarchy):
<style>
.group-header { background: yellow; zoom: 1; padding: 8px; }
.group-header:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
/* set width appropriately to allow room for button */
.group-header h3 { float: left; width: 300px; }
/* set line-height or margins to align with h3 baseline or middle */
.group-header input { float: right; }
</style>
<div class="group-header">
<h3>This is my title</h3>
<input type="button" value="Collapse"/>
</div>
If you want true vertical alignment in the middle (ie, if the text wraps the button is still middle-aligned with respect to both lines of text), then you either need to do a table or work something with position: absolute and margins. You can add position: relative to your drop-down menu (or more likely its parent) in order to pull it into the same ordering level as the buttons, allowing you to bump it above them with z-index, if it comes to that.
Note that you don't need width: 100% on the div because it's a block-level element, and zoom: 1 makes the div behave like it has a clearfix in IE (other browsers pick up the actual clearfix). You also don't need all those extraneous classes if you're targeting things a bit more specifically, although you might need a wrapper div or span on the button to make positioning easier.
Do a double float in a div and use the clearfix. http://www.webtoolkit.info/css-clearfix.html Do you have any padding/margin restrictions?
<div class="clearfix">
<div style="float:left">Title</div>
<input type="button" value="Button" style="float:right" />
</div>
<div class="group-header">
<input type="button" name="Button" value="Button" style="float:right" />
<span>Title</span>
</div>
I've chose to use Flexbox, because it made things so much easier.
You basically need to go to the parent of the children you want to align and add display:box (prefixed of course). To make them sit in the sides, use justify-content. Space between is the right thing when you have elements which need to be aligned to the end, like in this case (see link)...
Then the vertical align issue. Because I made the parent of the two elements, you want to align a Flexbox. It's easy now to use align-items: center.
Then I added the styles you wanted before, removed the float from the title and button in the header and added a padding:
.group-header, .group-content {
width: 500px;
margin: 0 auto;
}
.group-header{
border: 1px solid red;
background: yellow;
overflow: hidden;
display: -webkit-box;
display: -moz-box;
display: box;
display: -webkit-flex;
display: -moz-flex;
display: -ms-flexbox;
display: flex;
-webkit-justify-content: space-between;
-moz-justify-content: space-between;
-ms-justify-content: space-between;
-o-justify-content: space-between;
justify-content: space-between;
webkit-align-items: center;
-moz-align-items: center;
-ms-align-items: center;
-o-align-items: center;
align-items: center;
padding: 8px 0;
}
.group-content{
border: 1px solid black;
background: #DDD;
}
.group-title {
padding-left: 8px;
}
.group-buttons {
padding-right: 8px
}
See Demo
I agree that one should really only use tables for tabular data, for the simple reason that tables don't show until they're finished loading (no matter how fast that is; it's slower that the CSS method). I do, however, feel that this is the simplest and most elegant solution:
<html>
<head>
<title>stack header</title>
<style type="text/css">
#stackheader {
background-color: #666;
color: #FFF;
width: 410px;
height: 50px;
}
#title {
color: #FFF;
float: left;
padding: 15px 0 0 15px;
}
#button {
color: #FFF;
float: right;
padding: 15px 15px 0 0;
}
</style>
</head>
<body>
<div id="stackheader">
<div id="title">Title</div>
<div id="button">Button</div>
</div>
</body>
</html>
The button function and any extra detail can be styled from this basic form. Apologies for the bad tags.