Positioning CSS :after content - css

I'm trying to make a circular button with a character centered inside (in this case, a right-pointing arrow for a next button). I've gotten it vertically centered by adjusting the element's line-height, but I can't find a way to move it over to the side.
I tried adding both literal and unicode (\0020) space characters and that didn't move the triangle at all. Padding and margin don't work on the :after selector, and don't have the desired effect if applied to the element itself.
Here's the 'rendered' code, according to firebug (I'm using SASS, so pasting the actual code would leave out all the mixin definitions and such).
.flowbar--nav-image__next:after {
content: "▸";
}
.flowbar--nav-image:after {
color: white;
font-size: 19px;
}
.flowbar--nav-image {
background-color: #018FD6;
background-image: -moz-linear-gradient(center top , #93E3F7, #018FD6);
border-radius: 50% 50% 50% 50%;
display: inline-block;
height: 25px;
line-height: 25px;
width: 25px;
}
And the actual HTML:
<span class="flowbar--nav-image flowbar--nav-image__next"></span>
And here's what gets rendered:

This will work:
.flowbar--nav-image__next:after {
content: "▸";
display:block;
margin-left:10px;
}
http://jsfiddle.net/qTXFJ/1/
Or, instead, you could simply adjust the text alignment, which means you don't have to figure out the pixels yourself:
.flowbar--nav-image {
text-align:center;
}
http://jsfiddle.net/qTXFJ/3/

Related

inline-block goes under floated div

I'm trying to style my headings with display:inline-block; but i've a problem with a behavior of the property.
Jsfiddle : http://jsfiddle.net/Tu2GU/
See the titles, when a title has a long text, the heading goes under the floated div. I want the heading to break and then display 2 lines (or more) and stay on the left of the floated div, not under it.
Can't find anything helping, thanks !
edit : i updated the jsfiddle : http://jsfiddle.net/Tu2GU/13/ (removed % width for the floated div)
I don't want to have 2 divs side by side, the floated div on the right is meant to be right there, like a page summary giving link inside the page.
Also, heading are under the floated div (in html code) not over.
Since the right list uses a percent width, you can set a max-width with a percent width
h2 {
... Your original CSS ...
max-width:calc(75% - 40px); /* 40px comes from horizontal padding */
}
Demo
I'd recommend using a class to apply to each header instead of using the same max-width on each h1, h2, etc, but that's just personal preference
If the width of the right floated div is set, use calc(100% - 440px) or whatever the left horizontal padding + right width is
Create a float: left; container using the CSS below:
.lfloat {
float: left;
width: 75%;
}
You just have to wrap your text in a new div:
<div class="lfloat">
<!-- content -->
</div>
Demo
This will contain the content to the left and keep your sidebar to the right.
Note: You must clear your floats with clear: both;.
Why not try floating the elements on the left instead of using inline-block?
* {
font-family: Tahoma, Geneva, sans-serif;
font-weight: normal;
font-size: 1em;
}
.rfloat {
float: right;
width: 25%;
background: #9C3;
color: #111;
}
h1 {
float: left;
margin: 0;
padding: 10px 5%;
background: #06C;
color: #FFF;
}
h2 {
float: left;
margin: 0;
padding: 10px 5%;
background: #F33;
color: #FFF;
width:65%;
}
http://jsfiddle.net/g4Grv/
updated your Jsfiddle: http://jsfiddle.net/Tu2GU/12/
Main thing was a wrapping div around your h1 and p tag alongside of display:inline-block and vertical-align:top
Is this what you needed?
You have a few options. You can float the heading to the left so that it will slide up - you will have to set a width, though.
h2 {
float: left;
width: 80%;
}
Another option would be to set a max width. Since inline-block elements are technically block level, you can supply a width without breaking anything. You could try this:
h2 {
max-width: 80%
}
Yet another option would be to make the element inline. This will let the browser determine the best fit for the header.
h2 {
display: inline;
}
This will make the header wrap around the list and you may get the results you want. This method will make height and width parameters not work, so you will have to substitute those for line-height and padding

prevent :after element from wrapping to next line

I have this HTML:
<ul>
<li class="completed"><a href="#">I want the icon to stay on the same line as this last <strong>word</strong></li>
</ul>
I'm appending an icon using the :after pseudo element:
ul li.completed a:after {
background:transparent url(img.png) no-repeat;
content: '';
display:inline-block;
width: 24px;
height: 16px;
}
The problem: if the available width is too small, the icon wraps to the next line. I would want it to stay on the same line as the last word of the link it's appended to:
Is this doable, without adding 'nowrap' to the entire link (I want the words to wrap, just not the icon).
See jsFiddle here.
JSFiddle - http://jsfiddle.net/Bk38F/65/
Add a negative margin to the pseudo element, to compensate its width:
ul li.completed a:after {
background:transparent url(img1.png) no-repeat;
content: ' ';
display: inline-block;
width: 24px;
height: 16px;
margin-right: -24px;
}
Now, that is going to make the icon overflow the container, and the line is going to break only when the text meet the end of the line. If you need to maintain the icon inside the original container width, you can add padding to compensate again:
ul li.completed a {
display: inline-block;
padding-right: 24px;
}
IMPORTANT UPDATE:
For this method to work, there must be no white space between the text and the closing tag of the element holding the pseudo element. Even though the pseudo element's width is compensated by a negative margin, the white space will make the line break when it meets the edge of the parent element. For example, this works:
<span>text goes here</span>
and this doesn't:
<span>
text goes here
</span>
you can add the image to the last word instead. that will make it break together.
add a class to word
<strong class="test">word</strong>
and .test:after { ...
http://jsfiddle.net/52dkR/
the trick is also to make that class to be inline-block
and if you want to keep the underline see this.
http://jsfiddle.net/atcJJ/
add text-decoration:inherit;
This is a little similar to a previous answer, but I thought that I'd flesh it out and explain it fully.
As soon as you set display: inline-block, :after becomes a non-text-binding element. This is why it wraps, and why nowrap has no effect. So leave display alone.
As it's a text element by default, the content binds to previous text, as long as there's no whitespace between them. So don't add any, but make sure you have content: "", or it's the same as display: none. The only problem is height and width are controlled by the content, which in this case is collapsed. So width is 0, and height is the line height.
Resize the area with padding; left or right, it doesn't matter. Add a little margin so the icon doesn't touch the text. Keep everything as relative sizes (em, pt, etc.), and use background-size: contain, so that the icon scales with the text, like an emoji or font. Finally position the icon where you want with background-position.
ul li.completed a:after {
content: "";
background: url('icon.svg');
background-size: contain;
background-repeat: no-repeat;
background-position: center center;
margin-left: 0.2em; /* spacing*/
padding-right: 0.75em; /* sizing */
}
I've used this for my external links (a[href*="://"]:after), and it's worked fine in Firefox, Chrome, and iOS. And since the icon remains a text element, even direct text after it binds, so any closing punctuation will wrap too.
If using an icon font: Using the "non-breaking space" unicode \00a0 along with the pseudo-element content (in this case a Font Awesome glyph).
This works without any extra mark-up or special formatting or classnames.
a[href^='http']::after {
content: '\00a0\f14c';
font-family: 'Font Awesome 5 Pro', sans-serif;
line-height: 0;
}
The line-height: 0; part keeps the lines from twitching when the last 'word + icon' wrap.
CodePen example
I was having the same issue. I didn't really like the idea of adding strong or span tags to the last word, so I tried simply adding the icon as a background image with some padding-right instead of using the :after or :before pseudo elements. Worked for me!
<ul><li class="completed">I want the icon to stay on the same line as this last word</li></ul>
ul li.completed a {
background: url(img1.png) no-repeat 100% 50%;
padding-right: 18px;
}
http://jsfiddle.net/atcJJ/36/
I was attempting this with a link button and had the most success with adding padding to the right of the element as #Hugo Silva suggested, then setting the ::after to absolute position. This was a pretty simple solution and seemed to work across modern browsers.
.button {
position: relative;
color: #F00;
font-size: 1.5rem;
padding-right: 2.25rem;
}
.button::after {
content: '>>';
display: inline-block;
padding-left: .75rem;
position: absolute;
}
Here's a JS Fiddle.
Please make sure you end the tag before
<ul><li class="completed">I want the icon to stay on the same line as this last <strong>word</strong></li></ul>
Try the below css. Instead of using "after" use "before" and float right.
ul li.completed a:before {
background:transparent url(img1.png) no-repeat;
content: '';
display:inline-block;
width: 24px;
height: 16px;
float:right;
}
Please check this:
http://jsfiddle.net/supriti/atcJJ/7/
It is possible to do it without :after.
The element with background should be display:inline.
<h1><span>I want the icon to stay on the same line as this last word</span></h1>
h1 span {
padding-right: 24px;
background: url('icon.svg') no-repeat right top;
}
http://jsfiddle.net/my97k7b1/
The problem occurs when there is whitespace at the end of the text of the element, so it considers the icon as another word. My solution is to remove the white space with javascript and put it outside the element. Also, this way we avoid that text-decoration:underline styles the white space that may be at the end of a link:
$(document).ready(function () {
$("a[href$=\".pdf\"]").each(function () {
var endspace = /\s$/;
if (endspace.test($(this).html())) {
var linktx = $(this).html().replace(/\s*$/, "");
$(this).html(linktx);
$(this).after(" ");
}
});
});
In the css I add a non-breaking space \00A0 before the icon to separate it from the text, and to scale according to the font-size. In some cases, using a narrow no-break space \202F offers a better visual effect:
a[href$=".pdf"]:after {
content: "\00A0\f1c1";
font-family: "Font Awesome 5 Pro";
}
https://jsfiddle.net/poselab/910bw7zt/8/
With my particular set up, the only working solution was to use position relative, and place my icon element in a span with a position absolute. Like so:
h2 a {
position: relative;
width: auto;
}
h2 a span {
position: absolute;
right: -30px;
bottom: 0;
}
<h2>
<a href="#">
The arrow won't drop to the next line as an orphan, even if the text is long and responsive
<span>→</span>
</a>
</h2>
I just used:
white-space: nowrap;
Worked for me!

Placing an icon beside the text of an H1 tag by using a span

Here's the HTML I'm trying to use:
<h1>Order Not Paid<span class="not-paid"></span></h1>
Of course if there is a better way please say so.
Currently since there is no text inside of the span, it seems the browsers are ignoring this tag. Firebug shows up grayed out when inspecting.
When I place text in the span, the icon shows correctly.
What CSS rule can I apply for this effect? Here's what I have so far (It's SASS, but easy to grasp):
h1 {
font-size: 24px;
span.not-paid {
background-image: url('/Public/images/remove.png');
background-repeat: no-repeat;
}
}
I'd like the icon to appear where the span is.
Alternatively, is it kosher to do something like this? If so, I can settle with this as it looks good on IE8 and modern browsers.
<h1>Order Not Paid <img src="#Url.Content("~/Public/images/remove.png")" alt="" /></h1>
If the icon is small and not reused anywhere else just set it as part of the h1.
HTML:
<h1 class="not-paid">Order Not Paid</h1>
CSS:
h1.not-paid {
font-size: 24px;
padding:0 16px 0 0; /* whatever the dimensions the image needs */
background-image: url('/Public/images/remove.png') no-repeat right center; /* Position left/right/whatever */
}
A little cleaner this way.
the background image is not showing up because the span has no width, and therefore is not showing any of the background.
also, the snippet you gave is not valid css.
try something like this, assuming the image is 16px by 16px:
h1 {
font-size: 24px;
}
span.not-paid {
display: inline-block;
vertical-align: middle;
height: 16px;
width: 16px;
background-image: url('/Public/images/remove.png');
background-repeat: no-repeat;
}
The display: inline-block; is to make it so the width will apply. The vertical-align is to center the image on the middle of the line.
All of that said, the <img> tag solution would work too, but it doesn't scale well to a lot of similar images. The css-based solution makes it easier to switch to something like css spriting later.
In either case, you'll probably want to change your direct image urls to relative urls before expecting this page to work in a production environment.
I'm pretty sure that you need to give the span some width. By default it has none, so of course no background image will be seen.
First, if you are not using sass and less, your stylesheet is wrong. Next, give inner-block to span and the image height and width.
h1 {
font- size: 24px;
}
h1 span.not-paid {
width: 50px;
height: 50px;
display: inline-block;
background-image: url('/Public/images/remove.png');
background-repeat: no-repeat;
}

align icons with text

What's the best way to align icons (left) and text (right) or the opposite text on left and icon on right?
Does the icon image and text have to be the same size? Ideally I would like them to be different but be on the same vertical alignment.
I am using background-position css property to get the icons from a larger image.
Here is how I do it now, but I am struggling with either getting them to be on the same line or be vertically aligned to the bottom.
Text
This is what I get after I try your suggestions.
Though the text is now aligned with the icon, it is superimposed over the icon to the right of the icon that I want. Please note that i am using the background position to show the icon from a larger set of images.
Basically I am getting
<icon><10px><text_and_unwanted_icon_to_the_right_under_it>
<span class="group3_drops_icon group3_l_icon" style="">50</span>
group3_drops_icon {
background-position:-50px -111px;
}
.group3_l_icon {
-moz-background-clip:border;
-moz-background-inline-policy:continuous;
-moz-background-origin:padding;
background:transparent url(/images/group3.png) no-repeat scroll left center;
height:35px;
overflow:hidden;
padding-left:55px;
}
I usually use background:
<style type="text/css">
.icon {
background-image: url(path/to/my/icon.jpg);
background-position: left center;
background-repeat: no-repeat;
padding-left: 16px; /* Or size of icon + spacing */
}
</style>
<span class="icon">Some text here</span>
You can do it on the same line using vertical-align and line-height
<p style='line-height: 30px'>
<img src='icon.gif' style='vertical-align: middle' />Icon Text
</p>
Alternatively, you can go the background approach with no-repeat and positioning:
span.icontext {
background: transparent url(icon.gif) no-repeat inherit left center;
padding-left: 10px /* at least the width of the icon */
}
<span class="icontext">
Icon Text
</span>
Sadly, neither of these answers are bullet proof and each have one big flaw.
#rossipedia
I used to implement all my icons this way and it works quite well. But, and this is a big but, it does not work with sprites, since you're using the background-position property to position the icon inside the container that includes your text.
And not using sprites where you can is bad for performance and SEO, making them imperative for any good modern website.
#Jamie Wong
The first solution has two markup flaws. Using elements semantically correctly is sadly underrated by some, but you'll see the benefits in prioritizing form in your search engine ranking. So first of all, you shouldn't use a p-tag when the content is not a paragraph. Use span instead. Secondly, the img-tag is meant for content only. In very specific cases, you might have to ignore this rule, but this isn't one of them.
My Solution:
I won't lie to you, I've checked in a lot of places in my time and IMHO there is no optimal solution. These two solutions are the ones that come closest to that, though:
Inline-Block Solution
HTML:
<div class="container">
<div class="icon"></div>
<span class="content">Hello</span>
</div>
CSS:
.container {
margin-top: 50px;
}
.container .icon {
height: 30px;
width: 30px;
background: #000;
display: inline-block;
vertical-align: middle;
}
.container .content {
display: inline-block;
vertical-align: middle;
}
"display:inline-block;" is a beautiful thing. You can do so much with it and it plays very nicely with responsive design.
But it depends on your client. Inline-Block does not work well with IE6, IE7 and still causes problems with IE8. I personally no longer support IE6 and 7, but IE8 is still out there. If your client really needs his website to be usable in IE8, inline-block is sadly no option. Assess this first. Replace the black background of the icon-element with your sprite, position it, throw no-repeat in there and voilà, there you have it.
Oh yeah, and as a plus, you can align the text any way you want with vertical-align.
P.S.: I am aware that there's an empty HTML-tag in there, if anyone has a suggestion as to how to fill it, I'd be thankful.
Fixed Height Solution
.clearfix:after {
content: ".";
display: block;
clear: both;
visibility: hidden;
line-height: 0;
height: 0;
}
.clearfix {
display: inline-block;
}
html[xmlns] .clearfix {
display: block;
}
* html .clearfix {
height: 1%;
}
.container {
margin-top: 50px;
border: 1px solid #000;
}
.container .icon {
height: 30px;
width: 30px;
background: #000;
float:left;
}
.container .content {
line-height: 30px;
float: left;
display: block;
}
I hate this one. It uses a fixed line height for the text, and if you choose the same height as the Icon's box, the text is centered to that height. To align the text to the top, cut the line height, and as to the bottom, you'll have to fix that with position: absolute and a fixed width and height for the container. I'm not going to get into that unless someone requests it, because it's a whole issue for itself, and brings with it a lot of disadvantages.
The main disadvantage of this path is the fixed height. Fixed heights are always unflexible and especially with text, it can cause a bunch of problems (You can no longer scale the text as a user without it being cut off, plus different browsers render text differently). So be sure that in no browser the text is cut off and that it has some wiggle room inside its line height.
P.S.: Don't forget the clearfix for the container. And, of course, replace the black background with your sprite and according position + no-repeat.
Conclusion
Use inline-block if at all possible. ;) If it's not, breath deeply and try the second solution.

How to place text at the bottom when there's predefined height!

This should be incredibly trivial, but it's not. I have a predefined height for an anchor, and I would like to place the text at the bottom.
<li><a class="my-text">My Text</a></li>
I used the following CSS, which does not work. The text still appears at the top.
a.my-text {
background-color:#cccc;
height:50px;
vertical-align:bottom;
width:100px;
}
The idea is: I want to align text to the bottom, but if there is text that is longer than one line, I want the over flow to go to the top, not push everything else down... any ideas of how this could be achieved?
This can't be done using css and the html you provide. If you put an extra span in the anchor, it can be done:
a.my-text {
height: 50px;
display: block;
}
a.my-text span {
position: absolute;
bottom: 0;
}
You can use bottom:0px with position:absolute in anchor.
HTML
<li><a class="my-text">My Text</a></li>
CSS
li {
position: relative;
height:200px;
border: 1px solid red;
}
a.my-text {
bottom: 0px;
border: 1px solid blue;
position: absolute;
background-color:#cccc;
width:100px;
height:50px;
}
See in jsfiddle.
It definitely would not work, because <a> anchors are inline tags, therefore assigning them heights and widths is useless. The vertical-align property determines the positioning of inline elements with respect to the line they're in, not the vertical position of the text. (See http://reference.sitepoint.com/css/vertical-align) As far as I understand what you are requesting cannot be done. However, there are alternatives, as suggested above, to achieve similar effects.
The issue with your code is that the anchor won't respond to height/width because it is an inline element. If you you add a {display: block} to the anchor it's now a block element, but, as I recall, vertical-align doesn't work on the contents of block elements. This was the easiest way I could think of using display: table-cell.
a.my-text {
background-color: #ccc;
height: 200px; width: 100px;
vertical-align: bottom;
display: table-cell;
}
It sounds like you just need to get rid of the height rule on the anchor tag and use something like padding-top: 45px on the li

Resources