I wanted to know If I can use both px and em in the same CSS file (for same tags/class). What I mean by this is that, can I have something like this : -
body{
font-size: 10px;
font-size: 0.625em;
font-weight: normal;
font-family: arial;
margin: 0px auto;
color: #333333;
background: #E0E0E0;
}
My objective is to convert a very big CSS file that supports 'em' so that the user can decide the font size they would like to use. But my problem is the well documented issue with 'em' - the nested tags get affected.
I sought for help by using 'rem' in certain places instead of 'em'. Though it helped a bit, I lost the entire structure of the webpage.
I would like to keep the exact same font size in my webpage and still support the user wanting to change font size.
I am using jQuery to add a class to the body tag that would contain a specified font size and everything else should be scalable.
To address your sample css...
You can mix px and em (and percentage) to your heart's content. This is fine:
body{
font-size: 10px;
margin: 0px auto;
}
You cannot define the same css property twice. Well, technically you can, but only one of them will be applied. So this is broken:
body{
font-size: 10px;
font-size: 0.625em;
}
But it has nothing to do with mixing px and em. This is also broken:
body{
font-size: 10px;
font-size: 20px;
}
The good news is you're on the right track...
Define some top level container, or the body, with font-size in pixels.
Define every sub node with font-size in em.
Use javascript to change the top level container's font-size.
Here's an example fiddle: http://jsfiddle.net/pabo/pn1tyaxb/
Notice that the buttons, and indeed anything outside of the top level container you've chosen, will not be affected by rescaling.
I know this is not really the question, but I came here looking for another answer, so I will post it anyway. (About your question, obviously it makes no sense to define the same property twice with different units, but check the other answers for that.)
But yes you can use em and px in the same style sheet, and you can use em and px even in the same property!
body {
font-size: 12px;
}
.footnote {
font-size: 0.7em;
}
input {
padding: 0.5em;
border: 1px solid #666;
}
.input-replace {
padding: calc(0.5em - 3px);
border: 4px solid #eee;
}
When you use calc() you can make sure the size of the two elements is always exactly the same.
Use em units for any text (or other elements) that you want to scale based off the user's selection. And use rem units for things you want to stay the same size.
DEMO EXAMPLE
CSS: The REM units will be based off this value (base 10 for easy calc)
html { font-size:10px; }
HTML: User can select what size they want the page font to be
<select id="sizeSelector">
<option value="10px">Extra Small</option>
<option value="12px">Small</option>
<option value="14px">Normal</option>
<option value="16px">Large</option>
<option value="18px">Extra Large</option>
</select>
JS: Create a jQuery function bound to the select box that modifies the <body>font-size, thus changing your em based declarations:
$(document).ready(function() {
$("#sizeSelector").change(function(e) {
$("body").css('fontSize', e.target.value);
});
// initialize font size for first page load
$("#sizeSelector").prop("selectedIndex", 2).trigger('change');
});
Updated: Code is no longer dependent on classes
You cant define in the same css.But you can define like this.
.input {
width:100px;
}
<input width:0.1em;>
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>
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've been using rem sizing instead of px for all styling and have noticed if the user changes their browser font size to small, it will then remove the borders.
Here's a link as reference, just change your browser text settings from medium to small, the first div is with rem second is with px.
http://jsbin.com/pozex/1/edit
Actually you should not use rem for border size in my opinion (except for some rare cases maybe). Specially if you want to have a hair-line border then use 1px. There is nothing wrong with using pixels where they actually make sense.
We have used rem's with pixel fallback in large scale web projects but never used rem for the border sizes (but we have only used hair-line borders most of the cases). In my opinion units relative to font (rem, em, ch) should be used for content relevant elements such as font-sizes and negative space between content elements using padding / margin.
Sometimes even rem's are not the nicest solution. They are great because they are predictable in comparison to em's but you also loose a lot of dynamics. Recently we were following an idea by Chris Coyier to set a font-size in rem on component level (article, product teaser etc.) and then use em on sub-elements of the component. This gives you the flexibility to change the rem font-size on component level to scale the whole component content.
One workaround is to use box-shadow: http://jsfiddle.net/KsW2s/.
* {
padding: 0;
margin: 0;
}
html {
font-size: 10px;
}
body {
padding: 10px;
}
div:first-of-type {
background-color: white;
box-shadow: 0 0 0 0.1rem red;
margin-bottom: 2rem;
padding: 0 1.6rem;
}
div:last-of-type {
background-color: white;
border: 1px solid red;
padding: 0 16px;
}
I have this code:
<h1>Windows Store<br /><span class="smallSubText">apps</span></h1>
and:
#windowsStoreApplications {
float: right;
width: 50%;
font-size: 16pt;
text-align: center;
height: 182px;
background-color: #9DCA87;
border-top: 6px solid #AEDF66;
}
.smallSubText {
font-size: 16pt;
}
As you can see, both the h1 and span are set to the same font-size - this is not how I want it but it's how I made it because I noticed that the font-sizes were not matching up to how they should be.
I made them both the same size to demonstrate that they are both the same size in code, but when you run the site and look at it - they're actually different sizes.
Is this due to some size weirdness with the h1 element?
If #windowsStoreApplications is a div, then you need to delclare a #windowsStoreApplications h1{} markup in your css and style the element with font-size:16px; there. You are not selecting the h1 element otherwise.
Well first, if you havn't declared a font-size for your h1's (and the rest) the browser defaults will be implemented which vary in size.
Second, you should not be using pt for your size, you should be using px, em or %.
#windowsStoreApplications h1 {
font-size:16pt; /* or preffered unit */
}
After reading the thread
Input size vs width
I'm clear that we should not use size attribute but css style.
What will be the cross browser css that shows exactly same width for both input[text] and textarea?
BTB, I tried
#idInputText, #idTextArea {
font: inherit;
width: 60ex;
}
Is it correct? any better solution?
Thanks in advance for any help.
You will probably get more consistent results with different browsers by applying a CSS reset first. This article lists some good examples:
https://stackoverflow.com/questions/116754/best-css-reset
Once you have eliminated the subtle browser differences on padding and margins, then your master width of 60ex should allow the inputs to line up.
The native padding for text input elements differ. You will need to assign a different width to input elements and textarea elements and experiment.
#form input.textfield { width:10em; }
#form textarea { width:9em; }
Just throw some default styles ( I prefer ems ) and pop open Firebug and experiment by changing the size values.
I usually throw a class=textfield on <input type=text> so I don't target <input type=submit> or similar.
I would avoid a generic CSS reset, but use something like this:
input[type="text"], input[type="password"], textarea {
width: 60ex;
margin: 0;
padding: 2px; /* it's best to have a little padding */
border: 1px solid #ccc; /* gets around varying border styles */
border-radius: 4px /* optional; for newer browsers */
}
As long as you're in standards mode and not quirks mode this should work fine for most browsers.
Notes:
The attribute selectors - [type="text"] - don't work in IE6 so you may wish to opt for a class name instead.
You can't get all browsers to display form fields exactly the same way.
Using ex as the unit, whilst a good idea, might not work well in a fixed-pixel width environment.
Use pixel rather than EM or pct values. 60px = 60px across all browsers, regardless of base font size.
I'm late to this party, but in case anyone runs into this and needs to use ex's for width, I finally got it to work.
Textareas by default use monospace for their font-family. So, you'll need to override that. This css worked for me:
input[type="text"], textarea {
font-family: Arial, sans-serif;
border: 2px groove;
padding: 2px;
margin: 10px;
width: 35ex;
}
Here's a Fiddle to demonstrate: https://jsfiddle.net/Lxahau9c/
padding left and right 0px