Make text not wrap around icon in :before pseudoelement? - css

I have an icon in a :before pseudoelement, and if the textelement becomes to long and goes to the next row, I want it to not wrap around my pseudoelement but keep it's distance.
Here is a link to my example:
http://jsbin.com/yosevagaqa/1/edit?html,css,output
If you resize the window so that the text is forces into a new line, you can see the problem.
How can I avoid this?

As you can see from the other answers, there are multiple solutions!
If the size of the square in :before is always the same, one other solution would be to add
.link {margin-left:25px; text-indent:-25px;}
to the CSS. This causes the entire block to be shifted to the right, except for the first line, containing the square, which gets "outdented".
http://jsfiddle.net/MrLister/3xbfyqkh/
Or what I would prefer, with sizes in ems, so that the red square depends on the font size.
.link:before {
/* .. */
width: 1em; height: 1em;
margin-right: .5em;
}
.link {margin-left:1.5em; text-indent:-1.5em;}
Making sure, of course, that the indentation is the same as the size + the margin of the square.
http://jsfiddle.net/MrLister/3xbfyqkh/1/
Another approach, since the purpose is to make a custom "bullet", would be to treat the h5 like a list item. Then you won't need the ::before trick. You will need other tricks to make the square the right size though...
.link {
display:list-item; list-style:square;
color:red;
font-size:2em; line-height:.5em;
margin:.5em 0 .5em 1em}
.link a {
font-size:.417em; vertical-align:.3em}
http://jsfiddle.net/MrLister/3xbfyqkh/5/

You can add following CSS:
.link{
float: right;
width: calc(100% - 25px);
}

.link{
position: relative;
padding-left: 25px;
}
.link:before {
content: "";
background: red;
background-size: contain;
width: 15px;
height: 15px;
display: inline-block;
vertical-align: middle;
margin-right: 10px;
position: absolute; top: 0; left: 0;
}
<h5 class="link">A long link that might wrap and then it gets all weird and stuff</h5>

Related

Slanted Edge Buttons

I'm trying to build buttons that look like this:
I can accomplish this using :after and CSS triangles, but I can't get that working with variable height elements. Is there any way to accomplish this and keep variable height?
Fiddle: http://jsfiddle.net/AaP47/2/
You could use a skewed div in this case. The only issue here is that as your buttons get taller, due to the skew, they will get slightly wider. This may not be an issue if you are only dealing with 1 or 2 lines. If they get very tall it may cause things to noticeably not line up exactly:
http://jsfiddle.net/AaP47/3/
.button.triangle:after {
content: "";
background-color: red;
display: block;
height: 100%;
position: absolute;
right: -30px;
top: 0;
width: 60px;
transform: skewX(-10deg);
}
This is also not completely scalable. You would need to decide on the largest height you have to support and adjust accordingly. The taller you need to support, the wider the skewed div must be.
Result (without the red): http://jsfiddle.net/AaP47/4/
Just because I had fun tinkering in a different direction and to offer an option concept even though you apparently already got an answer;
a {
padding-right: 20px;
padding-left: 20px;
text-decoration: none;
color: white;
font-weight: bold;
display: inline-block;
border-right: 30px solid transparent;
border-top: 50px solid #4c4c4c;
height: 0;
line-height: 20px;
}
a p {margin-top: -45px;}
and;
<a href="#">
<p>this is a triangle button<br/>
with multiple lines!</p>
</a>
jfiddle: http://jsfiddle.net/AaP47/6/
Cheers!

Tooltips using only CSS

I am trying to make a tooltip for an anchor tag using only CSS. I have come this far. I am trying to achieve the functionality of having the box and the tip arrow positioned exactly at the center no matter what the length of the text is.
The above image is what I am trying to get at.
I've tried keeping the width:auto but it's not working either.
body
{overflow-x:hidden;}
div
{position:relative;width:700px;border:1px red solid;padding:20px;margin:0 auto;text-align:justify;}
a
{position:relative;white-space:nowrap;}
a > span.tooltip
{
position: absolute;
white-space: normal;
width: 100%;
top: 130%;
left: 0;
}
a > span.tooltip > span
{
position: absolute;
top: 0;
right: 0;
text-align: center;
bottom: 0;
left: -500%;
width: 1100%;
}
a > span.tooltip > span > span
{
display: inline-block;
background: black;
border-radius: 4px;
padding: 10px;
color: white;
max-width: 300px;
}
DEMO:
http://jsfiddle.net/b2Yqf/
works on msie 7 8 9 10, firefox, chrome
not what you might want... since markup is made with three nested <span>s... but YES. it could be done!
The main problem you're facing is that you need a white-space: nowrap this gets you about as far as hint.css by #robooneus. I can't figure out the centering either though. Any widths or margins are relative to the "Tooltip" link's width. A link to where you found the images might be helpful too so we can study the source.
EDIT1:
Additionally, a margin-left: -6px on the arrow (the :before) centers that on the word tooltip, it counteracts the move to the right by the border.
I don't think what you are trying to do (center the tooltip) is possible while having width:auto;.
If you declare a width, you can simple position the tooltip with:
.tooltip:hover:after {
width:100px; /* whatever you want */
left:50%;
margin-left:-50px; /* half the width */
}
EDIT
As #Alexander says in his answer, also repositioning your tooltip arrow using margin-left is a good idea, as it is slightly off center with just left:50%.

How can I get a top border tight to a font's glyphs?

I have need in a project to show rules at the baseline, x-height, and cap height of several font samples. I have baseline and x-height taken care of, but am having trouble getting a general CSS rule that will draw a border at the cap height of any font I apply the rule to. I've fiddled with the line height, but the space between a font's glyphs and the top of its layout box differs from font to font, so setting it once won't work for any font.
This Code Pen example illustrates the issue: http://codepen.io/DrSpatula/pen/BAgqG
You are now applying the line-height to the p. If you remove it there, and apply the line-height to the span.text, and set it to a value of 1.55ex, it shows properly.
So your CSS will be:
p {
font-size: 72px;
position: relative;
margin: 0;
padding: 0;
}
p span {
margin: 0;
padding: 0;
display: inline-block;
}
.sans {
font-family: sans-serif;
}
.text {
border-top: 1px solid blue;
line-height: 1.55ex;
}
.rule {
height: 1ex;
border-top: 1px dotted red;
border-bottom: 1px solid blue;
position: relative;
left: -7.25em;
width: 7.75em;
top: 1px;
}
It's very dirty, but have you tried a one pixel .gif as a repeating background then you can set it's position relative to the font?
maybe I can help.
I've made a small fiddle for you to view.
(http://jsfiddle.net/dgxJh/1/)
I fear however that with this solution you'll have to repostion the span with the pink line for every font-size and every font.
But in essence you'll position a span over your text by using following code:
span{
height: 1px;
width: 100%;
background: pink;
display: block;
position: absolute;
top: 0.6em;
}
don't forget to position your container relative

CSS navigation with cut-out notch as marker

I know I have seen this somewhere before, but I am trying to create a black fixed navbar with a marker that is transparent cut-out triangle. I need help getting the triangle cut-out to be transparent to the background, so when you scroll the page, you can see through to the content beneath:
I have a standard list/anchor navigation with a javascript to move the .current class depending upon the page section:
<div class="navbar">
<ul>
<li class="current"><a>home</a></li>
<li><a>products</a></li>
<li><a>services</a></li>
<li><a>contact us</a></li>
</ul>
</div>
styled with the following CSS:
.navbar {
width: 100%;
position: fixed;
background: black;
float: left;
}
ul, li {
list-style: none;
margin: 0;
padding: 0;
float: left;
}
a {
padding: 10px 20px 20px;
}
.current a {
background: transparent url('../img/wedge-red.png') center bottom no-repeat;
}
The only way I can think to do it is to add extra divs on either side of the ul and assign the background to them, and then use a transparent png with a cutout as the background of the li a's.
Is there a way to do this without getting really ugly like that, and adding extra divs?
Try CSS pseudo elements!
Add 2 free DOM elements before and after an existing element in the DOM. Ideal in cases when you don't want to add stuff to your markup to satisfy styling needs.
CSS Markup
.item:before {
content:"";
display: inline-block;
width: 20px;
height: 20px;
background-color: silver;
}
.item:after {
content:"";
display: inline-block;
width: 20px;
height: 20px;
background-color: gray;
}
HTML
<div class="item">Content</div>
Check this JSFiddle for a demo.
Make sure you set content: "" and display:block in order to see them.
Here's what I ended up with -- extending the borders and cropping them with overflow: hidden; (a little hacky, but it works and doesn't add elements to the DOM):
.navbar {
width: 100%;
height: 60px;
position: fixed;
overflow: hidden;
}
ul {
border-left: solid black 2000px;
border-right: solid black 2000px;
position: absolute;
top: 0;
left: 50%;
margin-left: -2000px;
}
The above worked nicely for my purposes, and behaves in a responsive environment.
The other answer on this page, using :before and :after pseudo elements didn't work for my purposes. It ended up being too fussy, the pseudo elements wouldn't align properly, and kept wrapping to the next line when the browser window was resized. That solution as suggested works with fixed-width elements, not percentages as was specified in the original question.

How can I make a fieldset legend-style "background line" on heading text?

I'm attempting to style heading text similar to how your default legend text appears in fieldsets; that is to say, I'd like a strikethrough-like line to come up to, but not through, the text. I can't seem to find any information on how I might accomplish this, and since on numerous other questions Google's always directed me to Stack Overflow for answers, I thought someone here may be able to give me advice.
For greater clarity. I'm attempting to get this effect on header text:
Centered Header Text
Is there any way to do this?
See: http://jsfiddle.net/thirtydot/jm4VQ/
If the text needs to wrap, this won't work. In IE7, there will be no line.
HTML:
<h2><span>Centered Header Text</span></h2>
CSS:
h2 {
text-align: center;
display: table;
width: 100%;
}
h2 > span, h2:before, h2:after {
display: table-cell;
}
h2:before, h2:after {
background: url(http://dummyimage.com/2x1/f0f/fff&text=+) repeat-x center;
width: 50%;
content: ' ';
}
h2 > span {
white-space: nowrap;
padding: 0 9px;
}
Edit:
<h2><strike> </strike>Your Text Here<strike> </strike></h2>
Here's how you can do it with a few simple tags and non-breaking spaces.
I'd use an image and call it a day, but this seemed to work for me:
CSS
fieldset {
border-right: 0px;
border-left: 0px;
border-bottom: 0px;
width: 200px;
}
legend {
margin: 0 25%;
}
HTML
<fieldset>
<legend>My Text Here</legend>
</fieldset>
That's the only way I could figure out how to do it with css. Note the width is fixed. Once again I wouldn't do this myself.
I came up with a quick, image-less solution that seems to work pretty well in IE 8+ and other browsers, whilst gracefully degrading in IE 6/7:
<h1>CSS 2.1 EXAMPLE</h1>
h1 { position: relative; text-align: center; }
h1:first-line { background-color: white; }
h1:before {
position: absolute;
z-index: -1;
content: '';
left: 0px;
right: 0px;
height: 1px;
top: 50%;
background-color: black;
}
It does come with the following limitations, though:
The text must match the overall background colour exactly, otherwise it will look weird.
If you want any kind of padding on the text, you need to use non-breaking spaces at either side of the text (see demo).
Heading text must always be on one line (works best if fixed width).
Here's a demo: http://jsfiddle.net/AndyE/3tFQJ/​
With flexbox being supported by all the latest browsers out there, and it being five years since the IE8 requirement was mentioned by the author, I wanted to have some fun building a new solution using that.
A variety of examples getting more complicated:
https://jsfiddle.net/0mL79b4h/1/
https://jsfiddle.net/0mL79b4h/2/
CSS
div {
display: flex;
align-items: center;
}
div:before,
div:after {
border: 1px solid #000000;
border-radius: 2px;
height: 2px;
display: block;
content: "";
flex: 1;
width: 100%;
}
h1 {
text-align: center;
margin: 8px;
}
HTML
<div>
<h1>Example Text</h1>
</div>
<div>
<h1>Multi-Line<br>Example Text</h1>
</div>
Pros:
Uses flexbox!
Super simple HTML.
Left and right sides can be adjusted for asymmetry.
Zero background issues, no inheriting colors, etc.
Fluid width.
Multi-Line support.
Left/Center/Right/Custom Alignment: Just adjust the flex property separately for the before and after elements, higher numbers will dedicate more space to that side. Remove one entirely to left or right align it.
Interesting effects by playing with the border style (I actually chose a round border in this example). Set height to 0px and use border-top instead for a generic line.
Cons:
Uses flexbox. Call me lazy, but I didn't build in any backward compatibility in this example so it'll look odd on a browser that supports psuedo elements but doesn't support flexbox, although last I checked that was Chrome (Firefox, etc), which are all automatically updated anyway. Might want to use some Modernizr.
Here is what I am using on a client's site: http://jsfiddle.net/TPgE4/
Pros:
No images needed - renders instantly
Uses padding to control space on both sides of text
Text can be center aligned, or left/right aligned — just add, e.g., margin-left: 8px or margin-right: 8px on h2 span style definition to make it look good
Cons:
Requires use of additional tag such as <span>...</span> inside heading tag
Text must fit on one line for good appearance
Background color on <span> element must match surrounding background color, so if you have a non-solid background image, gradient or pattern it won't match perfectly
Kind of late to the party, but this is my solution: https://jsfiddle.net/g43pt908/
Requires no images, and doesn't depend on a background color.
HTML
<div class="hr-text">
<span>Some text</span>
</div>
CSS
.hr-text {
border-top: 1px solid #999;
text-align: center;
background-color: inherit;
}
.hr-text span {
display: inline-block;
position: relative;
height: 14px;
top: -12px;
font-size: 14px;
font-style: italic;
color: #666;
background-color: inherit;
padding: 0 10px;
}
I'm not sure if this would suit your need...
h1:before, h1:after {
content: " ------------- ";
}
This doesn't feel like a very good answer, but I'm posting it anyway.
See: http://jsfiddle.net/rFmQg/
<h2><span>Centered Header Text</span></h2>
h2 {
background: url(http://dummyimage.com/2x1/f0f/fff&text=+) repeat-x center;
text-align: center
}
h2 span {
background: #fff;
padding: 0 9px
}
I don't like it because:
You have to use an image.
This. (it only works if the backgrounds match)
body { padding-top: 100px; }
div.parent {
text-align: center;
border-top: 1px solid #ccc;
}
div.parent div {
display: inline-block;
margin-top: -0.8em;
padding: 0 0.5em;
background: #fff;
}
<body>
<div class="parent">
<div>My Text Here</div>
</div>
</body>
This is a fluid-width solution that matches your design and should be ok in IE7 (though I'll admit I didn't check). There are a couple of downsides:
You lose the fieldset/legend semantics.
You can't put a transparent background on the text.
If you don't need it to be fluid-width, onteria_'s solution is probably your best bet.

Resources