Underline with padding: Non-links - css

Should the following line of CSS work for adding padding to regular underlines? Not links, just when I underline one or more words for emphasis. Nothing seems to change.
.underline {
padding-bottom: 2px;
border-bottom: black 2px solid;
}
Cheers!

Underlined text doesn't have a class .underline whose settings you could change. It has a setting: text-decoration: underline , which is not the same as border-bottom. Some browsers allow additional parameters for text-decoration to style it to a limited extent, see https://caniuse.com/#search=text-decoration . However, the results really often look different between different browsers...
.a {
text-decoration: underline;
}
.b {
border-bottom: 1px solid black;
padding-bottom: 3px;
}
<p>This is an example for <span class="a">underlined text</span> within a phrase. Usually a <span> element is used to apply "text-decoration: underline". The vertical distance to the baseline of the text depends on the browser and usually can't be changed.</p>
<p>A "border-bottom" is <span class="b">something completely different</span>. Here the distance to the text can be set manually by using a "padding-bottom".</p>

Related

In CSS how do I create a class to put padding underneath an underlined heading?

I have a context specific class that I want to certain headings on the site and I'm using the following code to apply a 2px full width line under a heading:-
.headingCustom2 {
color:black;
text-align: center;
padding-top: 50px;
border-bottom: 2px solid #000;
padding-bottom: 3px;
}
I want to add 20px padding beneath the underline so there's space between it and the div below. It needs to be independent of padding:bottom. My searching has only returned results on padding-bottom which alters the distance between the heading and the underline. Wanted to keep it to a distinct class as there's a lot of headings across the site it will need to be applied to. The heading font, Heading 5 is also used in other non-underlined contexts. Anyway, I hope this question isn't too tiresome.
You can try to use ::after
.headingCustom2::after {
content: '';
display: block;
height: 20px;
}

CSS inherited border color seems to be ignored

I have an anchor element that I want to draw a border around when the cursor hovers over it. The problem is that the anchor text and everything to its right "jumps" slightly to the right when the border is drawn.
I thought I'd be clever and style the anchor with a border of the background color (via "inherit") so that a default border is drawn when there is no hover. Then, when the user hovers, the red border is simply drawn over the background border and the text should not jump to the right. But this approach does not work.
The main reason I am posting is to understand why my strategy of using the inherited color to draw the border does not work. In other words, why is it that a border of the inherited color is not drawn? Secondarily, I would like to know how to prevent the text from jumping.
Here are the styles and a JSFiddle: https://jsfiddle.net/tlbaxter99/zoLr4m8j/6/
a:link, a:visited {
border: 1px solid inherit;
}
a:hover {
border: 1px solid red;
}
The main reason I am posting is to understand why my strategy of using the inherited color to draw the border does not work. In other words, why is it that a border of the inherited color is not drawn?
It's not working because 1px solid inherit is an invalid value:
According to MDN, you can't use the inherit value as part of a shorthand declaration (like in your case). Here is the relevant, in-depth quote:
Only the individual properties values can inherit. As missing values are replaced by their initial value, it is impossible to allow inheritance of individual properties by omitting them. The keyword inherit can be applied to a property, but only as a whole, not as a keyword for one value or another. That means that the only way to make some specific value to be inherited is to use the longhand property with the keyword inherit.
Which means that you would need to use the longhand border-color property in order to inherit the border-color value:
Example Here
a:link,
a:visited {
border: 1px solid;
border-color: inherit;
}
Secondarily, I would like to know how to prevent the text from jumping.
If you don't want the inherited border color, simply use a transparent border to displace the added border:
Example Here
a {
border: 1px solid transparent;
}
a:hover {
border: 1px solid red;
}
Alternatively, rather than using a border, you could also use the outline property to add an outline to the element that doesn't affect the element's box model:
Updated Example
a:hover {
outline: 1px solid red;
}
You need to tell the initial position about the border too. So initially, give transparent border, giving the space.
body {
padding: 1em;
}
a:link,
a:visited {
border: 1px solid transparent;
}
a:hover {
border: 1px solid red;
}
<p>
Hello This is a link and here is more text, <b>which doesn't move</b>.
</p>
Now it dares not to move. :) The reason why inherit doesn't work is, none would be the inherited value and it causes border to be 0px. (I am not sure, but that's what is compiled.)
instead of using inherit , try
transparent
Then your css class will look like the one below
a:link, a:visited {
border: 1px solid transparent;
}
This will make sure the border space is already taken and when you hover it doesn't hurt

How to select elements with some text after them?

I use <div> tags to insert icons in my pages:
<div class="icon warning"></div>There is a warning in the page
The problem is that the icons are too close to the text:
Here is the code for the icon:
div.icon{
display:inline-block;
width:16px;
height:16px;
background-color:transparent;
background-image:url(/images/icons.png);
background-repeat:no-repeat;
vertical-align:text-top;
background-position:0 0;
}
div.icon.warning{
background-position:-48px 0;
cursor:help;
}
I want to place a few pixels distance between the icon and the text only if the icon is being followed by some text. In other words if there is no text after the icon, I don't want that space. In other words for the following code, I want to have 5px distance between div#icon1 and the text "There is a warning in the page" but I don't want any distance between div#icon2 and the elements coming after it:
<li><div id="icon1" class="icon warning"></div>There is a warning in the page</li>
<li><div id="icon2" class="icon warning"></div></li>
Please note that the icons will not always appear within <li> elements so your suggested selectors cannot rely on the context that the icons may appear. The only thing certain about the icons is that if they are followed with some text, there must be some space between them and the text.
You can wrap the text around in a span and apply a padding to it:
<div class="icon warning"></div><span class="warning-text">There is a warning in the page</span>
.warning-text {
padding-left: 5px;
}
Update:
As per the comment below, I decided to change from using span instead of div.
It would be possible to use a div, but with the additional display: inline; CSS attribute.
If you are willing to restructure your markup a little (without adding any additional size to it):
http://jsfiddle.net/8kcQv/
The key line is:
.icon:empty{ padding-left: 20px; }
This works in IE 9, Chrome, etc. Other browsers will add extra space between empty elements. Here's an alternate version which degrades differently (less space between icon and text) when :empty is not supported:
http://jsfiddle.net/8kcQv/1/
HTML
<div class="icon">This message has text.</div>
<br>
<br>
<div class="icon"></div><div class="icon"></div><div class="icon"></div><div class="icon"></div><div class="icon"></div>
CSS
.icon{
padding: 4px 4px 4px 32px; /* 32px adds extra space to pad against text */
height: 24px;
line-height: 16px;
font-family: sans-serif;
font-size: 16px;
background:url(http://icons.iconarchive.com/icons/pixelmixer/basic/16/warning-icon.png) no-repeat 4px 4px;
display: inline-block;
}
/* empty matches elements with no children (including text nodes) */
.icon:empty{ padding-left: 20px; }
Alternatively, you might be able to do without :empty altogether if you use a style like:
.icon{
padding: 4px 8px 4px 24px;
...
}
This places equal distance on both sides of the icon.
I suggest using addClass jQuery. Add a certain class which will add a space if there is text after it, else don't put any class. You should set the default item with no space at all.

Control underline position on text-decoration: underline

Is there a way to control the position of the underline in text-decoration: underline?
Example link
The example above has an underline by default...is there a way to nudge that underline down by a few pixels so that there is more space between the text and the underline?
2020
Use text-underline-offset!
2012
The only way to do that is to use a border instead of an underline. Underlines are notoriously inflexible.
a {
border-bottom: 1px solid currentColor; /* Or whatever color you want */
text-decoration: none;
}
Here's a demo. If that's not enough space, you can easily add more — if it's too much, that's a little less convenient.
You can use pseudo before and after like this. It works well and is completely customizable.
CSS
p {
line-height: 1.6;
}
.underline {
text-decoration: none;
position: relative;
}
.underline:after {
position: absolute;
height: 1px;
margin: 0 auto;
content: '';
left: 0;
right: 0;
width: 90%;
color: #000;
background-color: red;
left: 0;
bottom: -3px; /* adjust this to move up and down. you may have to adjust the line height of the paragraph if you move it down a lot. */
}
HTML
<p>This is some example text. From this page, you can read more example text, or you can visit the bookshop to read example text later.</p>
Here's a more advanced demo with a screenshot attached I made that animates the underline on
hovering, changes colors, etc...
http://codepen.io/bootstrapped/details/yJqbPa/
There is the proposed text-underline-position property in CSS 3, but it seems that it has not been implemented in any browser yet.
So you would need to use the workaround of suppressing the underline and adding a bottom border, as suggested in other answers.
Note the the underline does not add to the total height of an element but bottom border does. In some situations, you might wish to use outline-bottom – which does not add to the total height – instead (though it is not as widely supported as border-bottom).
2021
There is the text-underline-offset property in CSS Text Decoration Module Level 4 which allows you to move the decoration by a specified distance away from its original position.
As of early 2020, this is only supported in Safari 12.1+ and Firefox 70+.
text-underline-offset property accepts these values:
auto - default, makes the browser choose the appropriate offset.
from-font - if the used font specifies a preferred offset, use that, otherwise it falls back to auto.
<length> - specify distance in the "usual" CSS length units. Use em to allow scaling proportionally with the font-size.
Example below:
p {
text-decoration: underline;
text-decoration-color: red;
margin-bottom: 1.5em;
}
p.test {
position: relative;
}
p.test::after {
position: absolute;
content: '';
display: block;
height: 1px;
width: 100%;
background: blue;
bottom: 0;
}
<p style="text-underline-offset: 0.75em;" class="test">
If you see our red underline <strong>below</strong> the blue line, this property works in your browser.
</p>
<p style="text-underline-offset: auto">
And now let’s try it with `text-underline-offset` set to `auto`.
</p>
<p style="text-underline-offset: from-font">
With `text-underline-offset` set to `from-font`, it probably looks the same as above.
</p>
2021
you can use text-underline-position: under;
<body>
<h1>
<a href="#"
style="text-decoration: underline; text-underline-position: under;" >
My link</a>
</h1>
</body>
for more details check https://developer.mozilla.org/en-US/docs/Web/CSS/text-underline-position
Use a border-bottom instead of the underline
a{
border-bottom: 1px solid #000;
padding-bottom: 2px;
}
Change padding-bottom to adjust the space
Using border-bottom-width and border-bottom-style will make the border the same color of the text by default:
text-decoration: none;
border-bottom-width: 1px;
border-bottom-style: solid;
padding-bottom: 1px;
There is one property text-underline-position: under. But only supported in Chrome and IE 10+.
More info: https://css-tricks.com/almanac/properties/t/text-underline-position/
https://developer.mozilla.org/en-US/docs/Web/CSS/text-underline-position
I would use border instead. Easier to control that.

CSS problem with Safari - renders link inside h1 with nasty uneven underline

I have something like this
<h1>
Home
</h1>
Very simple. IE, FF render it smoothly, underline works fine. Safari does this weird thing I've never seen before, it underlines "Home" only where the font serifs & curves DONT touch the underline, i.e. the letter "H" would get underline between the two "pillars" (sounds weird i know), and where those two touch the underline, the latter becomes much lighter in color (#eee vs #000).
UPDATE:
Apparently Safari's not rendering the link well when there's
text-shadow: 0px 2px 1px #fff;
Is there a particular reason for this?
The reason is because the text-shadow is rendered on the frontmost layer. If I were you I'd add a border-bottom to the h1 a element with no text underline.
h1 a {
text-decoration: none;
border-bottom: 1px solid blue;
}
Of course, replace blue with whatever colour your links are.
Edit: Realized that the shadow could be fixed with a span tag.
I think having a bit of space between the underline and the baseline when using the drop shadow looks better, but if you must have a text-decoration: underline you would have to add a span element to your markup:
<span>Home</span>
CSS:
h1 a span {
position: relative;
top: 0px;
z-index: -100;
}

Resources