Placing a fluid-width pseudo-element between two floated elements - html

EDIT: figured it out - see the answer below for solution.
Background: I have two elements, an h1 and a span. I'm trying to place the h1 "Title" element on the left of the container element and the span "category" element on the right of the container, which I've done with float: left and :right.
Problem: I'd like a dotted line to appear between the h1 and span elements. If possible, I'd like to use a pseudo-element for this since it's purely aesthetic, so I'm trying to get the h1:after pseduo-element to fill the remaining width of the container element between the h1 and span.
I'm trying to keep my HTML as close to the following as possible:
<header>
<h1>Title</h1>
<span class="category">Category</span>
</header>
My CSS so far - the :after pseudo-element is currently positioned beneath the h1 element, as opposed to between the h1 and span:
header {
display: block;
background: cyan;
width: 80%;
margin: 0 auto;
}
h1 {
display: block;
float: left;
}
h1:after {
display: block;
float: left;
width: 100%;
border-bottom: 1px dotted black;
content: " ";
}
span {
display: block;
float: right;
background: green;
}

use this code:
jsFiddle
HTML
<div class="container">
<span>title</span>
<span class="category">category</span>
</div>
CSS
div{
width:100%;
position:relative;
height:50px;
border:1px solid;
}
span{
line-height:50px;
background:#fff;
padding:0 10px;
float:left;
position:relative;
z-index:1;
}
span.category{
float:right;
}
.container:after{
content:"";
position:absolute;
width:100%;
height:0;
border-bottom:1px dotted #4c5660;
top:50%;
left:0;
}

OK after more research, I discovered that what I'm looking for is called a dot leader. While the W3C Working Draft has a section on them here, they don't seem to be well-implemented yet. I found another approach on SO here. Using that answer, I revised my code as follows:
HTML:
<header>
<h1>Title</h1>
<span>Category</span>
</header>
CSS:
header {
overflow: hidden;
}
h1 {
float: left;
padding: 0 .4em 0 0;
margin: 0;
}
span {
float: right;
padding: 0 0 0 .4em;
margin: 0;
}
/* Dot Leader */
header:after {
content: "";
display: block;
overflow: hidden;
height: 1em;
border-bottom: 1px dotted;
}
Here's a JSFiddle with the result: http://jsfiddle.net/dx48R/

Related

How to add line after text using css? [duplicate]

Im trying to make a line after each of my h2 tags. I canĀ“t figure out how I should tell the width, cause the lenght of the h2 headlines is differ from h2 to h2.
I use the :after method to create lines
h2:after {
position: absolute;
content: "";
height: 2px;
background-color: #242424;
width: 50%;
margin-left: 15px;
top: 50%;
}
Check code here: http://jsfiddle.net/s9gHf/
As you can see the line get too wide, and make the website too wide.
You could achieve this with an extra <span>:
h2 {
font-size: 1rem;
position: relative;
}
h2 span {
background-color: white;
padding-right: 10px;
}
h2:after {
content: "";
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 0.5em;
border-top: 1px solid black;
z-index: -1;
}
<h2><span>Featured products</span></h2>
<h2><span>Here is a very long h2, and as you can see the line get too wide</span></h2>
Another solution without the extra <span> but requires an overflow: hidden on the <h2>:
h2 {
font-size: 1rem;
overflow: hidden;
}
h2:after {
content: "";
display: inline-block;
height: 0.5em;
vertical-align: bottom;
width: 100%;
margin-right: -100%;
margin-left: 10px;
border-top: 1px solid black;
}
<h2><span>Featured products</span></h2>
<h2><span>Here is a very long h2, and as you can see the line get too wide</span></h2>
External examples: First, Second
There's no need for extra wrappers or span elements anymore. Flexbox and Grid can handle this easily.
h2 {
display: flex;
align-items: center;
}
h2::after {
content: '';
flex: 1;
margin-left: 1rem;
height: 1px;
background-color: #000;
}
<h2>Heading</h2>
using flexbox:
h2 {
display: flex;
align-items: center;
}
h2 span {
content: "";
flex: 1 1 auto;
border-top: 1px solid #000;
}
<h2>Title <span></span></h2>
Here is another, in my opinion even simpler solution using a flex wrapper:
.wrapper {
display: flex;
align-items: center;
}
.line {
border-top: 1px solid grey;
flex-grow: 1;
margin: 0 10px;
}
<div class="wrapper">
<p>Text</p>
<div class="line"></div>
</div>
External link
I notice that there are some flexbox implementations but they don't explain why and how to use it.
First, we just need one element, for this example h2.
We will change the element's display behavior to display: flex
Then, we center vertically its child elements using align-items: center.
h2 {
...
display: flex;
align-items: center;
}
Then, let's draw the line using the pseudo-element after.
We add '' to the content property to draw the element (we must).
Now lets make it flexible using flex: auto. This means that our element is sized according to its width and height properties. It grows to absorb any extra free space in the flex container, and shrinks to its minimum size to fit the container. This is equivalent to setting flex: 1 1 auto.
Then we add an small gap between the text and the line using margin-left: 1rem.
Finally, we draw a black line using border-top: 1px solid #000.
h2::after {
content: '';
flex: auto;
margin-left: 1rem;
border-top: 1px solid #000;
}
Here is functional snippet.
h2 {
font-size: 1em; /* not needed */
display: flex;
align-items: center;
}
h2::after {
content: '';
flex: auto;
margin-left: 1rem;
border-top: 1px solid #000;
}
<h2>Normal title</h2>
<h2>Very long title to test the behavior of the element when the content is wider</h2>
This is the most easy way I found to achieve the result: Just use hr tag before the text, and set the margin top for text. Very short and easy to understand! jsfiddle
h2 {
background-color: #ffffff;
margin-top: -22px;
width: 25%;
}
hr {
border: 1px solid #e9a216;
}
<br>
<hr>
<h2>ABOUT US</h2>
Here is how I do this:
http://jsfiddle.net/Zz7Wq/2/
I use a background instead of after and use my H1 or H2 to cover the background. Not quite your method above but does work well for me.
CSS
.title-box { background: #fff url('images/bar-orange.jpg') repeat-x left; text-align: left; margin-bottom: 20px;}
.title-box h1 { color: #000; background-color: #fff; display: inline; padding: 0 50px 0 50px; }
HTML
<div class="title-box"><h1>Title can go here</h1></div>
<div class="title-box"><h1>Title can go here this one is really really long</h1></div>
I am not experienced at all so feel free to correct things. However, I tried all these answers, but always had a problem in some screen.
So I tried the following that worked for me and looks as I want it in almost all screens with the exception of mobile.
<div class="wrapper">
<div id="Section-Title">
<div id="h2"> YOUR TITLE
<div id="line"><hr></div>
</div>
</div>
</div>
CSS:
.wrapper{
background:#fff;
max-width:100%;
margin:20px auto;
padding:50px 5%;}
#Section-Title{
margin: 2% auto;
width:98%;
overflow: hidden;}
#h2{
float:left;
width:100%;
position:relative;
z-index:1;
font-family:Arial, Helvetica, sans-serif;
font-size:1.5vw;}
#h2 #line {
display:inline-block;
float:right;
margin:auto;
margin-left:10px;
width:90%;
position:absolute;
top:-5%;}
#Section-Title:after{content:""; display:block; clear:both; }
.wrapper:after{content:""; display:block; clear:both; }

How to align h2 and p on same basline in div

I have a post header div with height of 70px/4.375em
In it is a category h2 and a p timestamp
I want it to be aligned as demonstrated in this picture
(made in Photoshop)
Here is my HTML:
<div class="post-header" style="background-color:#9377d8">
<h2 class="category">Technology</h2>
<p class="timestamp">Saturday, today</p>
</div>
And my CSS:
.post-header{
height:4.375em;
width:25em;
margin-bottom:0;
float:left;
}
.category{
color:white;
display:inline;
float:left;
margin:0.625em;
}
.timestamp{
color:white;
display:inline;
float:right;
margin:0.625em;
}
Please help me with the CSS to get the design that I want
You can change your CSS as follows:
.post-header {
height:4.375em;
width:25em;
margin-bottom:0;
display:block;
}
.category {
color:white;
display:inline-block;
width:45%;
margin:0.625em;
}
.timestamp {
color:white;
display:inline-block;
text-align:right;
margin:0.625em;
width:40%;
}
This way, you get better control over your layout since you can specify both the width and the vertical align of the element. As we're at it, I'd use percentages for margins, but of course it goes on you
Visit fiddle to see it in action
You could try the following. Instead of floats, use inline-blocks with text-align: justify.
This only works if there at least two lines of text, so generate an extra blank line with the pseudo-element .post-header:after.
.post-header {
height: 4.375em;
width: 25em;
margin-bottom: 0;
float: left;
text-align: justify;
}
.category {
color: white;
margin: 0.625em;
display: inline-block;
}
.timestamp {
color: white;
margin: 0.625em;
display: inline-block;
text-align: right;
}
.post-header:after {
content: "";
display: inline-block;
width: 100%;
}
<div class="post-header" style="background-color:#9377d8">
<h2 class="category">Technology</h2>
<p class="timestamp">Saturday, today</p>
</div>

Inserting elements before and after content

I have a headline and I want to insert a block with a certain background before and after the headline with the CSS pseudo elements :before and :after, and I want all them to float left so they're in one line.
The problem is that I can't figure out how to select the actual content of an element. Let's see this example realized with DIVs:
HTML:
<div class="line"></div>
<h1>Text here</h1>
<div class="line"></div>
CSS:
.line {
display: block;
width: 150px;
height: 20px;
float: left;
background-color: grey;
}
h1 {
display: block;
padding: 0 10px 0 10px;
width: 100px;
height: 20px;
font-size: 20px;
float: left;
margin: 0;
text-align: center;
}
So this will work. However, is there a way to realize the same with the :before and :after elements for h1? Can I somehow select the "Text here" and apply the :after class to it?
Thanks in advance!
EDIT:
Let me explain this in a different way. See this link: [link]http://css-tricks.com/examples/hrs/
I want to achieve the same as the last example, only instead of inserting the text via content: "$"; in the CSS, I want that dollar-sign to be inserted as a <h1>-element - ergo the "hr" to wrap around the h1.
If I'm understanding you correctly, you want something like this:
h1, h1:before, h1:after {
display:inline-block;
float:left;
}
h1 {
height: 16px;
width: auto;
position:relative;
padding:0 20px;
}
h1:before {
content: " ";
background:url(...);
height: 16px;
width: 16px;
position:absolute;
left:0;
}
h1:after {
content: " ";
background:url(...);
height: 16px;
width: 16px;
position:absolute;
right:0;
}

how to do a vertical align in my case

I am trying to do a vertical align for my texts. I also want to make sure the green background div need to cover from top to bottom inside the red color div. Currently the green color div only covers 90% of the red oolor div. I am not sure what happened in my case. Can anyone explain and help me out?
html
<div id='wrapper'>
<div class='head'></div>
<h2 class='title'>Warm-Up</h2>
</div>
css
.title{
display: inline;
padding-left: 15px;
vertical-align: middle;
margin: 0;
}
.head{
width: 30px;
height: 50px;
display: inline-block;
background-color: #A9D075;
}
#wrapper{
width:200px;
background-color: red;
}
http://jsfiddle.net/rmS2f/3/
Thanks.
Demo http://jsfiddle.net/rmS2f/6/
Your html structure will work but you need to change the styles:
.title {
display: inline-block;
padding-left: 45px;
vertical-align: middle;
margin: 0;
line-height:50px;
}
.head {
position:absolute;
left:0;
width: 30px;
height: 100%;
display: inline-block;
background-color: #A9D075;
}
#wrapper {
position:relative;
width:200px;
height:50px;
background-color: red;
}

Layout problems with CSS

I got some problems with layouting in CSS. Here is the code I am talking about: Fiddle.
The <div id="header"> should have the height of the <div id="menubuttons"> which I marked red.
I always thought that if you don't state the height of a div it will get the height of it's children.
The <div class="contentLine> is stuck to the <div id="theme"> although I defined margin-top: 20px;.
The right column always has greater margin than the left column. I want both to have the same margin to the browser window.
CSS
body {
margin: 0 auto;
padding: 0;
font-family:'Share', cursive;
}
#header {
width: 100%;
vertical-align: middle;
}
#header_logo {
width:;
float: left;
margin: 11px 20px 20px 20px;
background-color:;
}
#menubuttons {
margin-right: 0;
margin-top: 0;
height: 2.5em;
line-height: 2.5em;
display: inline-block;
background-color: red;
}
#menubuttons ul {
list-style-type: none;
margin:0;
padding:0;
}
#menubuttons li {
float: left;
margin-right: 20px;
}
a {
font-family:'Share', cursive;
}
a:link {
text-decoration:none;
}
a:visited {
text-decoration:none;
}
a:hover {
text-decoration:underline;
}
a:active {
text-decoration:underline;
}
#theme {
width: 100%;
height: 400px;
background-color: green;
margin-top: 0;
float: left;
}
.contentLine {
margin: 0 auto;
margin-top: 20px;
width: 96%;
}
.contentLine .column {
float: left;
margin: 0;
width: 30%;
margin-right: 1%;
padding: 1%;
position: inherit;
/* shadow for seeing div boundaries */
box-shadow: 0 0 1px black inset;
}
.contentLine #last {
margin-right: 0;
}
Let me go 1 by 1
1) Your <div id="header"> contains floated elements, you need to clear that, so use overflow: hidden; on parent element i.e #header
2) Again, you've floated #theme but you've set it to width: 100%; so you don't need float there.
3) About the last you need to set the margins accordingly, right now it's 1% so you need to calculate this correctly, I would like to suggest you to use box-sizing: border-box; and set 33% width for each element and than apply padding-right
Demo
Also make sure you clear your floating elements which are nested inside contentLine.
If you are not one of those IE fans, than you can use the snippet below, which will self clear the parent element in a better way.
.clear:after { /* Much much better than overflow: hidden; */
content: "";
display: table;
clear: both;
}
Update your html
</ul>
<!--Menu ends here -->
</div>
<!--menubuttons ends here -->
<!--Add following div to your code -->
<div class="clear"></div>
</div>
<div id="theme">
Update your CSS
.clear{
clear:both;
}
This should help.
- will be reusable also.