Please read the question carefully. It's not the same as the one about How to remove the space between inline-block elements.
Consider the following HTML:
body {
/* font-family: Arial; */
}
.my-class {
display: inline-block;
margin: 0 0 0 -4px;
background-color: transparent;
border: 1px solid #ccc;
padding: 20px;
}
<div>
<button class="my-class">Hello</button>
<button class="my-class">Stack</button>
<button class="my-class">Overflow</button>
</div>
Which produces:
But, if I add:
body {
font-family: Arial;
}
it results in a 1px space between the second and third buttons:
The question is: Why adding font-family to the body affects the space between the buttons?
It happens because each font has different width, even for the space character. You already know about the whitespace issues with inline-blocks. So, when you set Arial, those whitespaces change their width slightly from the browser's default font (or any other font with different width), which is Times New Roman in my case.
See how drastic the change is when you set the monospace font.
Now, why it happens between the 2nd and the 3rd box and not the 1st and the 2nd one? I'm pretty sure it comes down to rounding pixel values based on the width of the words entered, seems like there is a pseudo sub-pixel rendering present in the background, yet the decimal values get rounded in the final render process. See what happens if you use Arial and print Hell Stack Overflow instead of Hello Stack Overflow - the gaps look the same. So, it's just an undesired coincidence.
Another point that proves this is a rounding issue is the change in the gaps across various page zoom levels. It's fairly common to get these pixel mismatches in the layout when dealing with decimals in HTML. Zooming adds another dividing/multiplication stage, which changes the core values even further, resulting in completely unpredictable behaviour in the final layout.
It's because you're displaying the buttons as inline-block elements and when you have inline elements whitespace is significant and is rendered in the same way that spaces between words is rendered.
i.e inline-block makes whitespace significant, so spaces in the source between inline-block elements will be rendered.
For example: You could center the inline-block elements just by adding text-align: center; the same way is used to center the text in its parent block element. - DEMO
Why adding font-family to the body affects the space between the buttons?
Different fonts can have different spacing between words, If you compare font-family: monospace; with font-family: sans-serif; then you will see the monospace fonts have more space between words than sans-serif fonts and the inline-block elements is also rendered in the same way and have the spacing between elements.
Monospace DEMO
Sans-serif DEMO
The best way to remove the space between inline-block elements is adding the font-size: 0; to the parent element.
DEMO
div {
font-size: 0;
}
.my-class {
display: inline-block;
border: 1px solid #cccccc;
padding: 20px;
font-size: 16px;
}
<div>
<button class="my-class">Hello</button>
<button class="my-class">Stack</button>
<button class="my-class">Overflow</button>
</div>
The answer assumes that DirectWrite is enabled. You will not notice the specified symptoms and fractional widths otherwise. It is also assumed that default serif and sans-serif fonts are Times New Roman and Arial.
Whoever said that the space character is 4px wide is mistaken:
$(function() {
$(".demo").each(function() {
var width = $("span", this).width();
$("ins", this).text("total width: " + width + "px, " + (width / 10) + "px per space)");
});
});
.demo {
white-space: pre;
overflow: hidden;
background: #EEE;
}
.demo-1 {
font: 16px/1 sans-serif;
}
.demo-2 {
font: 16px/1 serif;
}
.demo-3 {
font: 16px/1 monospace;
}
.demo span {
float: left;
background: #CF0;
}
.demo ins {
float: right;
font-size: smaller;
}
<script src="//code.jquery.com/jquery-1.9.1.min.js"></script>
<p>The green blocks contain 10 spaces:</p>
<p class="demo demo-1"><span> </span><ins></ins></p>
<p class="demo demo-2"><span> </span><ins></ins></p>
<p class="demo demo-3"><span> </span><ins></ins></p>
Note that:
For a given size the character width depends on font family.
The character width does not necessarily have to be a whole number. Serif font gives you a nice whole number (4px), but Sans-serif font gives you fractional number (4.4px).
You could get different results in different browsers depending on how they handle fractional gaps between two blocks (e.g. 4.4px for 16px Arial). CSS specs are silent about this.
In Chrome with DirectWrite enabled, spaces are rendered as 4px and 5px alternately due to rounding off. This explains why there is no gap between first and second button and 1px gap between second and third. Try adding more buttons in your original example and notice how the pattern repeats (Demo).
Using margin-left: -4.4px seems to work but it is not guaranteed to work. Consider going back to the alternate solutions.
PROBLEM:
this happens because the display is set to inline-block.
inline-block is:
The element generates a block element box that will be flowed with
surrounding content as if it were a single inline box (behaving much
like a replaced element would)
»» see more about display property here: DISPLAY INFO
SOLUTION(S):
Remove the spaces
Negative margin
Skip the closing tag
Set the font size to zero
Just float them instead
Just use flexbox instead
For more details on each solution check
Fighting the Space Between Inline Block Elements
my preferred solutions from above is
Set the font size to zero
therefore is a snippet with your code and my preferred solution:
div {
font-size:0;
}
.my-class {
display: inline-block;
border: 1px solid #cccccc;
padding: 20px;
font:normal 12px Arial;
}
<div>
<button class="my-class">Hello</button>
<button class="my-class">Stack</button>
<button class="my-class">Overflow</button>
</div>
Plus, here is a snippet with your EXACT CODE only changing the font-family from body to the elements that have display:inline-block, and achieving the same output as my FIRST SNIPPET
.my-class {
display: inline-block;
margin-left: -4px; /* Remove the space between inline elements */
border: 1px solid #cccccc;
padding: 20px;
font-family:Arial;
}
<div>
<button class="my-class">Hello</button>
<button class="my-class">Stack</button>
<button class="my-class">Overflow</button>
</div>
EDIT:
OP's question:
Why adding font-family to the body affects the space between the
buttons?
in web typography there are:
Sans-serif
Fonts that do not have decorative markings, or serifs, on their letters. These fonts are often considered easier to read on screens.
Serif
Fonts that have decorative markings, or serifs, present on their characters.
Monospace
Fonts in which all characters are equally wide.
Cursive
Fonts that resemble cursive writing. These fonts may have a decorative appearance, but they can be difficult to read at small sizes, so they are generally used sparingly.
Fantasy
Fonts that may contain symbols or other decorative properties, but still represent the specified character.
Since Arial is a sans-serif font, therefore a non-fixed width font ( like monospace ), when applied to body with child elements displaying inline-block(without fix for the gaps) it will create space between the child elements.
Although if you apply the font-family to the child elements, like I DID in my 2ND SNIPPET it doesn't happen anymore.
one comment of an article:
The gap between inline elements is, as you suggest, a space character.
The width depends on the font (family, variant, etc.) and approximates
to .25em
you can check it here
the full article is below
ARTICLE
DEMO
The problem is that there are hidden spaces (a line break and a few tabs counts as a space, just to be clear) between tags. Minimize the HTML or comment the spaces out and everything will work correct:
body {
font-family: Arial;
}
.my-class {
display: inline-block;
margin-left: -4px;
border: 1px solid #cccccc;
padding: 20px;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<div>
<button class="my-class">Hello</button><!--
--><button class="my-class">Stack</button><!--
--><button class="my-class">Overflow</button>
</div>
</body>
</html>
Check the demo and use this CSS. If you have not satisfied, just change the font size. It will get fixed.
body {
font-family: Arial;
font-size: 15px;
}
.my-class {
display: inline-block;
margin: 0 0 0 -4px;
background-color: ccc;
border: 1px solid #ccc;
padding: 20px;
}
<div>
<button class="my-class">Hello</button>
<button class="my-class">Stack</button>
<button class="my-class">Overflow</button>
</div>
See also JSfiddle.
I recommend to use
float:left
or
float:right
instead
display:inline-block;
use the below css for this:
.my-class {
display: inline-block;
margin-left: -4px;
border: 1px solid #cccccc;
padding: 20px;
margin-right:-1px;
}
Related
I have this code:
<p style="line-height: 1;overflow: hidden;">blah_blah</p>
<p>blah_blah</p>
<p style="line-height: 1;overflow: hidden;">qypj;,</p>
<p>qypj;,</p>
which results in (notice no underscore, and cut characters):
That is, it behaves that way in Firefox (66.0.3 on Windows 10). Other browsers seem to render the underscore. The above snippet runner also seems to work (even in Firefox), unless you run it in "Full page".
This Q is similar to Text changes height after adding unicode character except there are no tricks here. "_" is just a simple ASCII character.
My question is which behavior is the correct one.
Is specific character allowed to change line height (I thought it was only supposed to be font dependent)? Shouldn't line-height: 1 imply it can fit exactly any text?
I suppose some characters are special, such as "p", "g", "j" (and possibly "_") that draw below its line. Still which behavior is the correct one. Is it considered overflow or not?
PS: Furthermore I find it funny either overflow-x: hidden;overflow-y: visible; and overflow-x: visible;overflow-y: hidden; still causes this. Which seems more like an actual bug to me.
My question is which behavior is the correct one.
All of them are correct because we don't have the same default font in all browsers and it's also different depending on the OS.
Is specific character allowed to change line height (I thought it was only supposed to be font dependent)?
Character doesn't change line-height. To be more accurate, line-height is a property that can only be changed by setting line-height but you are probably confusing with the line box that is defined by the line-height and a character alone cannot change it.
Shouldn't line-height: 1 imply it can fit exactly any text?
Not necessarely, line-height:1 means that the line box will be equal to the 1xfont-size 1 but is the font designed to include all the character inside this space? Probably most of them will do but we don't know.
Basically, you have two things to consider. The content area that is defined by the font properties and the line box that is defined by the line-height. We have no control over the first one and we can only control the second one.
Here is a basic example to illustrate:
span {
background:red;
color:#fff;
font-size:20px;
font-family:monospace;
}
body {
margin:10px 0;
border-top:1px solid;
border-bottom:1px solid;
animation:change 2s linear infinite alternate;
}
#keyframes change {
from {
line-height:0.2
}
to {
line-height:2
}
}
<span >
blah_blah
</span>
The red is our content area and its height is defined by the font properties and if you inspect the element you will see it has a height equal to 23px (not 20px like the font-size) and the borders define our line box that we control using the line-height.
So if the line-height is equal to 1 we will have a line box equal to 20px which is not enough to contain the 23px of the content area thus it will get truncated and we may probably hide some characters (or a part of them) which is logical:
span {
background: red;
color: #fff;
font-size: 20px;
font-family: monospace;
}
body {
margin: 5px;
line-height: 1;
overflow:hidden;
}
html {
overflow:auto;
}
<span>
blah_blah ÂÄ j p
</span>
a different font-size will remove the underscore in Firefox:
span {
background: red;
color: #fff;
font-size: 26px;
font-family: monospace;
}
body {
margin: 5px;
line-height: 1;
overflow:hidden;
}
html {
overflow:auto;
}
<span>
blah_blah ÂÄ j p
</span>
Another example with a Google Font where the result should be the same cross browser. The underscore is visible but not the ^/¨
span {
background: red;
color: #fff;
font-size: 26px;
font-family: 'Gugi', cursive;
}
body {
margin: 5px;
line-height: 1;
overflow:hidden;
}
html {
overflow:auto;
}
<link href="https://fonts.googleapis.com/css?family=Gugi" rel="stylesheet">
<span>
blah_blah ÂÄ j p
</span>
Another example where the underscore is not visible:
span {
background: red;
color: #fff;
font-size: 27px;
font-family: 'PT Sans', sans-serif;
}
body {
margin: 5px;
line-height: 1;
overflow:hidden;
}
html {
overflow:auto;
}
<link href="https://fonts.googleapis.com/css?family=PT+Sans" rel="stylesheet">
<span>
blah_blah ÂÄ j p
</span>
You can clearly see that we have a different overflow everytime we use a different font which confirms that this is font related. We have no control over it unless we know how the font is designed.
Related questions:
Understanding CSS2.1 specification regarding height on inline-level boxes
Why is there space between line boxes, not due to half leading?
Line height issue with inline-block elements
Here is a good article to get more accurate details and calculation: https://iamvdo.me/en/blog/css-font-metrics-line-height-and-vertical-align
A quote from this article:
It becomes obvious that setting line-height: 1 is a bad practice. I remind you that unitless values are font-size relative, not content-area relative, and dealing with a virtual-area smaller than the content-area is the origin of many of our problems.
1 : I considered a simplified explanation but in reality the calculation of the line box is not only relate to the line-height property.
The default line-height (depending on the font-family) when not otherwise specified is about 1.2 in most browsers. This includes Firefox.
This would explain why the underscore did not show in FireFox when the line-height was set to 1 - the bottom was of the line was cut off. So I don't think it's entirely to do with the font (although this does contribute), but also browser defaults.
Some font-sizes are bigger than other even at seemingly the "same" font size (as I'm sure you've seen when typing documents in e.g. Georgia vs Times new Roman/Baskerville ; so you wouldn't be guaranteed that text would always show on a specified line height of 1 (or 1.2). There are ways of measuring a font in pixels however
Hope this helps
If I use the browser tools in Firefox to inspect my snippet below, there is no height difference between the lines with and without underscore. The only difference is caused by the line-height setting: 16px with line-height: 1, 19.2 px with the browser's default line-height. So the underscore doesn't make a difference here (Firefox 66.0.3 on Mac), and it is visible in both cases.
Note that I set margins to 0 to see the "pure" line-height without distances between the lines. Also, I didn't specify a font-familiy setting, so the default font of the browser for p tags is used.
The only reason for what you describe which I can think of is a font with very particular dimensions/settings, where the descenders (i.e. the parts of letters like p q j which extend below the baseline) are not inside the line-height as defined by the font.
After a bunch of comments back and forth: I suppose it could be caused by the different default (system) fonts on Windows and Mac. Still a bug, I would say (if you are using the default font).
html,
body {
margin: 0;
padding: 0;
}
p {
background: #fb6;
margin: 0px;
}
<p style="line-height: 1;overflow: hidden;">blah_plah</p>
<p style="line-height: 1;overflow: hidden;">blah plah</p>
<p>blah_plah</p>
<p>blah plah</p>
I try to make a span look consistent between Firefox and Chrome browsers.
Chrome always seems to add a little extra whitespace at the bottom of the text in the span. Firefox does not.
My code:
<span style="line-height:22px; padding: 0px; margin:0px; border-radius: 3px;
vertical-align:middle; background-color: #cc0000; color: #fff; font-size: 22px;">
100%</span>
Try it on https://jsfiddle.net/j904g5fn/3/
You'll see that in the current version of Chrome, there is a little space under the text, which I can't remove by using padding, margin, line-height or vertical-align settings. Firefox does seem to display the span correctly.
How do I remove that extra space?
The three attempts (jsfiddle,inline-block,line-height 18)
The first answer shows the same problem in incognito modus. (there is a little more margin in total, but still more on the bottom)
The second answer:
Could it be a specific issue of Chrome on Linux? (v 68.0.3440.84)
Since <span> is not a block element by default, add display:inline-block; to make it work.
<span style="line-height:22px; padding: 0px; margin:0px; border-radius: 3px; vertical-align:middle; background-color: #cc0000; color: #fff; font-size: 22px; display:inline-block;">100%</span>
The problem is that you need to define the element as a type of block (such as inline-block) to accept margins and paddings, as well as the line-height being the same as the font size, which adds some additional spacing based on the glyph rendering of the font. By setting line-height to 0.75, you are specifying a unitless value, allowing it to scale up and down based on font size without affecting the spacing of the text within the box.
<span style="display:inline-block; line-height:0.75; border-radius: 3px; background-color: #cc0000; color: #fff; font-size: 28px;">100%</span>
This is my problem in short: https://jsfiddle.net/b6wLwkfs/
Long story: I have a div with some text in it. It initially creates some space on top and bottom of my div (this is not padding). I would like my div to only cover the text and not create extra space. This is my only css:
div {
background-color: black;
color: white;
font-size: 50px
}
<div>This is the text</div>
What I am looking for is to narrow down the div to only contains the text without creating any space on top of bottom. I acknowledge that if you tweaking a bit with px, you will achieve that but I am looking for more generic approach since font size will be different by cases.
Your code below is missing a (;) after font-size: 50px; now to achieve the space reduction I suggest you use line-height with the same font-size refer to my correction
Your Code
div {
background-color: black;
color: white;
font-size: 50px
}
My Correction
div {
background-color: black;
color: white;
font-size: 50px;
line-height: 50px;
}
There is likely no 'generic' way to do this, as that spacing you're seeing is actually part of the font face, and whatever adjustments you make to solve the 'problem' for this font, will not necessarily work on other fonts.
For example, just take a look at how Arial displays, as it's different than the default font that is used without setting a specific font-family, and as such a fix for the default font would likely have to be adjusted for Arial.
p {
background-color: black;
color: white;
font-size: 50px;
line-height: 1;
font-family: arial;
display: inline;
}
<p>
Oh hi i'm different
</p>
In the above snippet I've added a line-height of 1 to help normalize the spacing a bit. You could try to adjust further with setting the line-height to be at, or close to the exact font-size in pixels, but this will likely result in undesired spacing if you have lots of text in the element (text should also be in an appropriately semantic element like a p, or li, not just in a div).
In the end, can you achieve the result you're looking for? Definitely. Using things like line-height, margins and/or transforms. But you are likely not going to find a silver bullet to achieve the effect you want, consistently, if swapping out font faces.
As Sebastian Brosch mentioned in the question's comments, working off from Is it possible to change inline text height, not just the line-height? is likely going to be your best path forward.
I have an issue while using custom font(poppins-regular.ttf). The issue is when I set background-color for span tag which is wrapper of text.
The words like g,y,.. etc got cut at the bottom. But, If I change the font-family from poppinsRegular to tahoma it looks good.
But the real issue here is i need to maintain same line-height
.passageBody, .passageBody2 {
width: 414px;
padding: 10px 0;
margin: 0px;
font-size: 24px;
line-height: 32px;
font-family: 'Poppins', sans-serif;
}
.passageBody2 {
font-family: tahoma;
}
.highlightPhrase {
background-color: yellow;
}
<link href="https://fonts.googleapis.com/css?family=Poppins" rel="stylesheet">
<div class="passageBody">
<span>“Good-bye to you and your funny feet.</span>
<span class="highlightPhrase">Thanks for all the eggs to eat!” I was speaking to Bess, our chicken, and Mother laughed.</span>
</div>
<hr/>
<div class="passageBody2">
<span>“Good-bye to you and your funny feet.</span>
<span class="highlightPhrase">Thanks for all the eggs to eat!” I was speaking to Bess, our chicken, and Mother laughed.</span>
</div>
Example jsFiddle link here...
You can either remove the line-height property or try to set it in em units.
line-height: 1.5em;
Edit 1
If you don't want to change line-height, use vertical align with inline display
.highlightPhrase {
background-color: yellow;
display: inline;
vertical-align: text-bottom;
}
Edit 2
The above code might have visually changed the line height. So this example might be an elegant solution to your problem. Just wrap the content in another element and set the position to relative, so that background of each line will not hide the above line.
.highlightPhrase span {
position:relative;
}
or you can use some small image as background and repeat it to highlight entire text.
Problem here is the vertical placement of the glyphs.
Designer decided to set the font glyphs like that.
So, basically designer decided how much space there is below the baseline, and how much space is above the height of uppercase letters. Typically these spaces are equal, but they don't need to be.
I think that only solution for you is to put bigger line-height on the paragraph that is using that font or just choose a different font.
Change:
line-height: 32px; to line-height: auto;
Try this
.highlightPhrase {
padding:5px;
}
I am currently designing a web page with em units. I guess I don't understand it as well as I thought I did because a problem has occurred while I tried to align two separate span tags with margin-left. They were placed in the upper-left corner of my header. They were positioned on top of one another using display:block. When I used margin-right to align both the span tags, the larger span and the smaller tag didn't align correctly. I used the same number for margin-right, but they were still messed up.
Is this because I'm using em's?
How can I fix this?
I will paste the code I'm using below so you'll get a sense of what I'm working with. Hopefully I've explained this well enough.
HTML
<div class="header1">
<span class="title">Title goes here</span>
<span class="subtitle">This is the subtitle</span>
</div>
CSS
body {
color: #333;
font-family: 'lucida grande', tahoma, verdana, arial, sans-serif;
font-size: 62.5%; /* 10px */
line-height: 1.28;
}
.main1 {
width: 96em;
/* horizontally center the website layout */
margin: 0 auto; margin-top: .8em;
text-Align: left; /* override body {text-align:center} */
}
div.header1 {
clear: both;
width: 100%;
height: 9em;
background: #ff0000;
color: #fff;
}
.title {
font: small-caps 700 3.7em "Goudy Old Style", Garamond, "Big Caslon", "Times New Roman", serif;
}
.subtitle {
font-weight: lighter;
font-size: 1.4em;
}
The description of the problem is very confusing and does not explain what you want to achieve and what is your best attempt at that. You refer to left and right margin, but neither of them is set in your code for the elements discussed. You refer to setting display: block, but there is no such setting.
I will assume that you want the main title to appear (in the xy plane) above the subtitle. For this you need to set display: block or, better, use div markup instead of span or, best, use adequate heading markup such as h1 and h2 with due consideration of their default effects on vertical margins and font weight (i.e., overriding them in CSS if needed). And I assume that you wanted them left-aligned the same amount.
It seems that you did not take into account the relativity of the em unit. By definition, it equals the font size of the element (except in font-size, where it equals the font size of the parent element).
I suspect that you tried setting the left margin of both span elements using the same value such as 1em. But it does not mean the same for both elements, since their em sizes differ. If you wanted to set the their left margins to, say, the font size of the first element, you would set
.title { margin-left: 1em; }
.subtitle { margin-left: 2.6429em; }
The number 2.6429 is the ratio of the font sizes, calculated from 3.7/1.4.
It would be easier to just set a left margin on the enclosing div element. Its font size equals the font size of the body element, so if you wanted to set it to the font size of the main heading, you would use
div.header1 { margin-left: 3.7em; }
check the bellow link I hope this will help for you
http://kyleschaeffer.com/best-practices/css-font-size-em-vs-px-vs-pt-vs/
px: pixels (a dot on the computer screen)
em: 1em is equal to the current font size. 2em means 2 times the size of the current font. E.g., if an element is displayed with a font of 12 pt, then '2em' is 24 pt. The 'em' is a very useful unit in CSS, since it can adapt automatically to the font that the reader uses.
see the reference
So, you can use px instead em, its good practice.
Hope it will helps you. Thanks. !!