CSS: Strike-through not centered through the text - css

We are using strike-through to actually show oldprice vs new price for a product.
If you open this link, at the bottom of the page, we have a product on sale.
http://www.gkelite.com/Gymnastics-Shopby-GiftoftheWeek
The strike-through for the old price is not centered vertically for the text.
Can any one help out as to why it's happening?

A strike-through is traditionally some percentage (70% to 90%) of the x-height (or the height of a lower case 'x'). If the line were at the 50% of cap-height, it may be possible the strike-through would be above or at the top of any lowercase letter in the set. A strike-through is supposed to put a line through all letters in the text, which is why is gauged from the x-height.
Whether or not browsers actually use the x-height for their strikethrough calculation, this tradition is why is why strike-throughs are displayed short of the 50% of cap height.
See the following illustration for some examples of the terms:

I found a solution for it utilizing psuedo elements http://jsfiddle.net/urjhN/
.strike-center {
position: relative;
white-space: nowrap; /* would center line-through in the middle of the wrapped lines */
}
.strike-center:after {
border-top: 1px solid #000;
position: absolute;
content: "";
right: 0;
top:50%;
left: 0;
}
However this technique fails if the text is wrapped between lines, the line would be centered among those lines.
It seems to work among all major browsers; for IE7 (and prior) you could just fallback to the classic line-through using conditional comments.

There is no way to control the offset/placement of a strike-through, but, there is a way for controlling this using for text-decoration: underline using the below combination:
span {
background: lightyellow;
text-decoration: underline;
text-underline-offset: -40%; /* <-- this */
text-decoration-skip-ink: none;
}
output { display:inline-block; width:50px; }
<output>-40%</output>
<input type='range' min='-100' max='100' value='-40' oninput='this.nextElementSibling.style.textUnderlineOffset=this.value+"%"; this.previousElementSibling.innerHTML=this.value+"%"'/>
<span>Text with strike-through</span>
👉 Here's a Codepen of mine with an alternative strike-through approach:
https://codepen.io/vsync/pen/KKQoVRZ

Related

CSS text-overflow equivalent that trims at word boundaries? [duplicate]

In my webpage I have a div with fixed width and using the following css:
width: 200px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
The ellipsis is working, the problem is that it cuts the final word, and I wanted it to put the ellipsis (...) in the final of a full word.
For instance, if I have the text: "stackoverflow is the best", and if it need to be cutted near the end, I want it to display "stackoverflow is the ..." instead of "stackoverflow is the be..."
I’m afraid it’s impossible. There was once text-overflow: ellipsis-word, which would do just this, but it was not implemented in browsers and it was removed from CSS3 drafts.
Of course it's possible. (If you're willing to change your markup a bit.)
https://jsfiddle.net/warphLcr/
<style>
.foo {
/* Make it easy to see where the cutoff point is */
border: 2px solid #999;
padding-right: 18px; /* Always have room for an ellipsis */
width: 120px;
height: 1.1em; /* Only allow one line of text */
overflow: hidden; /* Hide all the text below that line */
background-color: #fff; /* Background color is required */
}
.foo > span {
display: inline-block; /* These have to be inline block to wrap correctly */
position: relative; /* Give the ellipsis an anchor point so it's positioned after the word */
background-color: #fff; /* Cover the ellipsis of the previous word with the same background color */
white-space: pre; /* Make sure the only point where wrapping is allowed is after a whole word */
}
.foo > span:after {
position: absolute; /* Take the ellipsis out of the flow, so the next item will cover it */
content: "…"; /* Each span has an ellipsis */
}
.foo > span:last-child:after {
content: ""; /* Except for the last one */
}
</style>
<div class="foo">
<!-- These *must not* have white space between them, or it will collapse to a space before the next word, and the ellipsis will become visible -->
<span>stackoverflow</span><span> is</span><span> the</span><span> best</span>
</div>
There's a jQuery plugin that does this, called dotdotdot.
It also works for multi-line text, and adapts responsively if the text reflows e.g. if the screen size changes. It also includes smart truncation of pathnames e.g. http://example.com/some/long/.../path.html
Be aware of the possibility of width-based timing issues in cases where the width changes or becomes unavailable in ways the plugin might not expect, such as if the text is initially hidden or if it changes font (e.g. loading web fonts on some browsers). Might require re-applying or being applied after such changes.
But 99% of the time, the plugin seems fast and robust.
If you want to display one line of text that would end in ellipsis, like a news ticker for example, just do:
p { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

CSS underline and letter-spacing

In a website menu, I have implemented some wishes of my customer concerning typography in CSS. She needs a different tracking on the font, no problem. But, she wants the active link to be underlined. As I have not implemented the code to target the active link, I just underlined them all to see how it would look. The CSS is as follows:
.main-navigation a {
display: block;
color: black;
font-weight: bold;
letter-spacing: 0.45em;
line-height: 4.5em;
text-decoration: underline;
text-transform: uppercase;
}
And this is the result:
The problem is that the letter spacing kind of messes up the underlining. I've drawn some vote magnets freehand circles to indicate the problem. The line starts nicely at the left side but is extended with the value of letter-spacing to the right.
Screenshot is from Firefox 25. Jsfiddle to see for yourself.
I could solve this using borders and using margins instead of line height, but is this fixable otherwise?
CSS Text underlining too long when letter-spacing is applied?
http://jsfiddle.net/isherwood/JWcGh/2
.main-navigation a:after {
/* absolute positioning keeps it within h1's relative positioned box, takes it out of the document flow and forces a block-style display */
position: absolute;
/* the same width as our letter-spacing property on the h1 element */
width: 0.45em;
/* we need to make sure our 'mask' is tall enough to hide the underline. For my own purpose 200% was enough, but you can play and see what suits you */
height: 200%;
/* set the background colour to the same as whatever the background colour is behind your element. I've used a red box here so you can see it on your page before you change the colour ;) */
background-color: #fff;
/* give the browser some text to render (if you're familiar with clearing floats like this, you should understand why this is important) */
content: ".";
/* hide the dynamic text you've just added off the screen somewhere */
text-indent: -9999em;
/* this is the magic part - pull the mask off the left and hide the underline beneath */
margin-left: -.40em;
}

How do I reduce the distance between the border-bottom and parts of text?

I'm currently building my website and I've run into a problem. Here is the webpage.
I want to add 3px underlines to only the links, like this:
The line height of the text is 56pt, so the border-bottom is far too far away from the links. text-decoration: underline is too thin, and way too close.
They need to be about half this distance. As negative padding doesn't exist, how should I go about fixing it?
Now used to this code (This is demo)
Css
.HomeText p a {
color: red;
text-decoration: none;
position: relative;
display: inline-block;
vertical-align: top;
}
.HomeText p a:hover:after{
content:'';
position:absolute;
left:0;
right:0;
bottom:-3px;
border-bottom:solid 1px red;
}
Demo LInk
Try adding the following:
display: inline-block;
height: 1.2em;
Haven't tested extensively, but seems to close the gap nicely in modern browsers.
Answer 1: Accept that css has limitations and work round them.
Answer 2: The only way I can thing of doing this is a using a span displaying it is a block and adding a border and padding to the bottom - this process will open up a whole other can of worms though floats blocks inline text etc. So I would go back to answer 1.
did you try this?
a {
border bottom: 3px red;
}

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.

Is it possible to specify line weight for "text-decoration: line-through;" in CSS?

The default weight of 1px for line-through property in CSS is great for body copy at 1em.
Unfortunately for larger items such as a price set at 3em on an offer site, 1px is really too light. Is it possible to set a heavier line weight for line-through?
If not, what alternatives should I consider, such as an image overlay for example?
You can do something like this in modern browsers
.strike{
position: relative;
}
.strike::after{
content: '';
border-bottom: 4px solid red;
position: absolute;
left: 0;
top: 50%;
width: 100%;
}
I <span class="strike">love</span> hate hotdogs
Made a fiddle of it too:
http://jsfiddle.net/TFSBF/
Here's another way to do it with a fake strike-through (which looks great and works on all browsers, albeit with the cost of a tiny imageload). The image is a black 1px by 2px box.
del {
background: url(/images/black-1x2.png) repeat-x 0 10px;
}
I think this is a browser implementation issue.
See this page http://jsbin.com/arucu5/2/edit
In IE8 and Firefox the line through width increases with the font size.
However in Safari and Chrome it remains at 1px
You can always a dirty Ghetto method like this
http://www.overclock.net/web-coding/167926-ghetto-css-strike-through.html
This should work:
<style>
span.strike {
font-weight:bold; /*set line weight here*/
color:red;
text-decoration:line-through;
}
span.strike>span {
font-weight:normal;
color: black;
}
</style>
<span class="strike"><span>$20.00</span></span>
I've found another approach to set line weight for multiline text:
span {
background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAADCAIAAADdv/LVAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAASSURBVHjaYvrPwMDEAMEAAQYACzEBBlU9CW8AAAAASUVORK5CYII=');
background-repeat: repeat-x;
background-position: center;
}
Here is an example:
http://output.jsbin.com/weqovenopi/1/
This approach assumes repeating an image (1px width and npx height). Also it works independent on the font-size.
Only one disadvantage - background renders under the text.
You can thicken the line with style.
For example:
text-decoration-thickness: 3px;

Resources