CSS, relative font size - css

Is it possible to set a font size to a percentage of the container size? I have a list of items which have an image, a header and a description. The image resizes automatically as the user resizes the window. I would like the header font to do the same.
edit: Javascript/JQuery is fine.

In CSS3, there is the vw unit, which stands for 1/100 of the viewport width. For example,
h1 { font-size: 5.5vw; }
sets the heading font size to 5.5% of the viewport width.
However, this seems to work on IE 9 (Standards Mode) only so far. Moreover, IE 9 does not dynamically change the value of the unit when the browser window is resized, only on reload.

Just to expand on Tyler's answer, this is what javascript is meant for, though I'm tad sure you can achieve the same feat using CSS3 viewports, you will be better off using jQuery (it's usually in the cache of most browser's and always hosted on Google so no need to worry :)
If you have a css like this:
#body #mytext {
font-size: 50%;
}
you can dynamically resize in jQuery like this:
$(window).resize(function(){
$('#body #mytext').css('font-size',($(window).width()*0.5)+'px');
});

No, this can only be done in JavaScript.

Is jquery is an option?
Super easy if it is: fiddle
<div id="container">
<p>HELLO WORLD!</p>
</div>​
<script>
$(document).ready(function() {
var sizeMe = ($('#container').height() / 100) * 90; /* 90% of container */
$('p').css('font-size', sizeMe);
};
</script>

I've done it with jquery in the past. Check out this article if it's of any interest to you. You can also use CSS to detect device width (not browser, and it's not supported in older browsers).
http://css-tricks.com/resolution-specific-stylesheets/

Related

vh / % units and keyboard on mobile devices

I have problem with units like vh / % for heights. When any input is active, keyboard on mobile devices change elements height. I'm looking for solution to change it to static height when keyboard is active.
jsfiddle (open on mobile device)
The issue is quite straightfoward, we've all experienced it before.
Luckily I rarely work on websites that have elements that need to fit perfectly based on the viewport sizes, however when I do, I prefer to use a jQuery solution to achieve this.
I am going to go out on a limb and assume that you only need to apply this type of rule on mobile, so am going to add this to the code.
jQuery(document).ready(function($){ //wait for the DOM to load
if($(window).width() > 640) { //check if screen width is less than 640px (i.e. mobile)
$('#my-element').css({ 'height' : $(window).height() });
}
});
It is possible to edit the height directly by changing the action to:
$('#my-element').height($(window).height());
but we specifically want to overwrite your CSS rule that stated something along the lines of:
#my-element { height: 100vh; }
I've edited your codepen to include my example.

CSS vh units inside an iframe

I'm trying to use CSS vh units inside of an iframe. I'm finding that they are scaled to the size of the iframe somehow. In other words, 100vh isn't the windowheight. It's set to the height of the iframe.
Does this seem right?
Is there a workaround?
I know this is an old question, but as people move toward the vh unit, this question will become much more common.
To clarify, here's an example of the problem. We have an HTML file that loads an iframe:
<!DOCTYPE html>
<html>
<head></head>
<style>
iframe {
height: 50vh;
width: 100%;
}
</style>
<body>
<iframe src="iframe.html"/>
</body>
</html>
And its iframe:
<!DOCTYPE html>
<html>
<head></head>
<style>
div {
height: 50vh;
width: 100%;
background: blue;
}
</style>
<body>
<div></div>
</body>
</html>
The important thing to note here is that both the iframe and the iframe's div element are designated as having a height of 50vh. The intended behaviour may be that the iframe honor the parent context's viewport height or width. Instead, the result looks like this:
That is, the height of the blue element is ~25% of the browser window, instead of the expected 50% (100% of the iframe). Although we may wish the iframe to respect the viewport of its parent, this example makes a good case for how unintuitive that may be, though it surely would make the v* units more valuable for content being iframe'd in. The problem has to do with how viewport height is determined.
From the spec:
The viewport-percentage lengths are relative to the size of the initial containing block. When the height or width of the initial containing block is changed, they are scaled accordingly.
Both an iframe and the browser window can be the initial containing block, as they are both valid viewports. A viewport is not limited to the browser window, but instead is defined as a window or other viewing area on the screen through which users consult a document.
An iframe creates a nested browsing context when inserted into a document, and thus is its own viewport.
So yes, this is the intended behaviour - and unfortunately there is no pure CSS workaround - however, www139 has provided an example of how this can be accomplished using JavaScript. The problem with this begins when many elements' size are controlled using v* units.
This is an excellent question. Sadly, I haven't been able to figure out a solution in CSS but I have been able to figure out a solution in JavaScript which I think is your best bet at the moment. Remember that the frames must be on the same domain for this to work.
Hope this helps. If this answer needs improvement, please comment below :-)
Solution in Theory (can't use here on SO because of frame origin issue):
window.addEventListener('load',function(){
initializeV();
function initializeV(){
//1% of the parent viewport width (same as 1vw):
var vw = window.parent.innerWidth/100;
//1% of the viewport height (same as 1vh):
var vh = window.parent.innerHeight/100;
//assign width and height to your v unit elements here
}
window.parent.addEventListener('resize',function(){
//when the browser window is resized; recalculate
initializeV();
});
});
Edit (Dec. 2018): In the comments, I was asked to supply an example. I can't do an exact example because the codepens on Stackoverflow load over a different frame origin than the page. However, I can mimic the effect. For practical applications, please reference the code snippet above. This snippet is meant merely to illustrate how it works.
Practical Application. Uses the concept explained above but without frame reference.
window.addEventListener('load',function(){
initializeV();
function initializeV(){
//note: I can't use window.parent becuase the code snippet loads on a different frame than the parent page. See the other snippet for a practical example. This snippet is meant to merely illustrate the effect.
//1% of the parent viewport width (same as 1vw):
var vw = window.innerWidth/100;
//1% of the viewport height (same as 1vh):
var vh = window.innerHeight/100;
//this is where the magic happens. Simply set width/height/whatever to a multiple of vw/vh and add 'px'. Dimensions must be in pixels since the vw/vh measurement is based on pixels.
document.getElementById('test').style.width = 30*vw+'px';
document.getElementById('test').style.height = 50*vh+'px';
//assign width and height to your v unit elements here
}
window.addEventListener('resize',function(){
//when the browser window is resized; recalculate
initializeV();
});
});
#test{
background:red;
}
<div id="test"></div>

ckeditor consume all available height?

Any way i can have ckeditor consume 100% height dynamically?
http://jsfiddle.net/bobbyrne01/jejmqjxa/1/
html
<div id="outer">
<textarea class="ckeditor" id="editor1" name="editor1"></textarea>
</div>
<button>test</buton>
css
#outer {
width: 95%;
height:500px;
}
While checking the ckeditor docs it is not supported yet to set the height in %
http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-height So to get the desired result I suggest to set the height to 100% by CSS but not by the ckedtior.config read the screen height with javascript, set the size on load and window resize and put it as value in the outer element height.
Might sounds like a lot of work but is not as tricky. Updated fiddle here
CSS to add (to get all ckeditors you might have on the loaded page)
div[id^=cke_editor] {
height:100%;
}
Javascript to set the height of the outer div on page load
document
.getElementById("outer")
.style.height = window.innerHeight+"px";
If you want to have this working on window resize I suggest to use jQuery but however you can do it without. Here is how (with and without jQuery): Cross-browser window resize event - JavaScript / jQuery

How can <footer>/<header>/<div>'s with 100% width, yet discrepancies in mobile browsers, be combatted?

After migrating a website to responsive html5 using media queries, I find that I still can't get the mobile iOS 7 safari browser to display the footer/main/header sections at the same width, despite their css being set to display:block and width:100%.
Examples:
http://i.imgur.com/QUxffNT.jpg
http://dev.shermanbrothers.com (username: devreview password: De3e3vfr4 ) [html5 update to site]
And a similar problem occurs even on an older version of the site:
http://i.imgur.com/1sS4WRZ.jpg
http://shermanbrothers.com [OLD version of the site with table-based layout, still has similar issues]
Now, I have some guesses as to -why- this is happening on mobile and not on the narrow windows of a desktop browser:
Some block level elements like the main/between-header-and-footer one have too much content to even shrink down to that 100%
Or perhaps using display:table on the middle section is allowing it to blow up larger than the other block & 100% width elements.
But I don't know what techniques to use to combat the problem.
- I can't even inspect the code via mobile to determine the reasons for the differences.
- setting a css max-width to images (eg max-width:100% ) within their container is not better.
So how can mobile-specific bugs, and mobile width/layout issues especially, be debugged & dealt with?
The tables are a huge headache for diagnosing this problem since there is so much markup to look through. However, the tables are not the reason why your layout is breaking (at least not with the markup I saw when I came across this question). Your problem is that you have so many fixed widths on images, text and table columns.
To fix this, you will have to set-up breakpoints in your media queries. Something like this for the images:
#media (min-width: Whatever is the smallest screen size the image will not break your layout) and (max-width: 1 pixel below the previous size where the image was so wide it broke your layout) {
.header-image {
width: whatever is the widest width that keeps it from breaking your layout; // This will change with smaller queries
height: auto;
}
}
And something like this for your fonts:
#media (min-width: Whatever is the smallest size the font will not break your layout) and (max-width: 1 pixel below the previous size where the font was so wide it broke your layout) {
.navbar-font {
font-size: whatever is the biggest font size that keeps the font from breaking your layout;
}
}
Alternatively for your fonts, you could tell them to wrap as the screen gets smaller, but then you would have to factor in their height as they wrapped:
.navbar-font {
white-space: pre-wrap;
}
Do something similar with the above to allow the width of your table columns to resize properly as well.
Also, follow #TylerEich 's suggestion and configure your viewports.
https://developer.apple.com/library/ios/documentation/AppleApplications/Reference/SafariWebContent/UsingtheViewport/UsingtheViewport.html
http://developer.android.com/guide/webapps/best-practices.html
Finally, check out BrowserStack for mobile browser testing.
This may not fix all of your layout issues, but it fixed the biggest ones I found. Table-based layouts are a pain to work with. Good luck :)
font-size
the top element of the footer columns (footer-flex) has a font-size: 10px. And the child element (.footer-block) has a font-size: 2em. This means the .footer-block elements have font-size: 20px. (10px(top element font-size) * 2em) = 20px. This causes big texts in your footer.
display
You're using float to align elements side by side which is a very bad practice. If you'd like to align elements properly you should select display: table-cell or display: inline-block. The difference is table-cell is just like <td> tag. Which means all the consecutive elements has the same height.
Because table-cell acts just like td tag the table-cell cannot have margins. If you'd like to have margins for your table-cell you need to provide a top element which is display: table with a style border-spacing. An example which is very proper for your case: http://jsfiddle.net/R3zDu/
As you can see there is no clear: both or float: blah definitions and clear css definition.
This doesn't mean "don't use float anymore". float's main purpose is to align the images in the texts/paragraphs.
clear all the float and clear: both styles.
apply table-cell method.
testing
I don't think there is a software that renders the page just like a mobile phone. On the other hand, if you have problems in iOS you can take a look at Safari browser in your PC or Mac which acts like iOS Safari in most cases (at least in your case).
Sounds like you need a mobile-friendly <meta> tag. Example:
<meta name="viewport" content="width=device-width, user-scalable=no">
Quote from the Mozilla Developer Network:
A typical mobile-optimized site contains something like the following:
<meta name="viewport" content="width=device-width, user-scalable=no">
The width property controls the size of the viewport. It can be set to a specific number of pixels like width=600 or to the special value device-width value which is the width of the screen in CSS pixels at a scale of 100%. (There are corresponding height and device-height values, which may be useful for pages with elements that change size or position based on the viewport height.)
The initial-scale property controls the zoom level when the page is first loaded. The maximum-scale, minimum-scale, and user-scalable properties control how users are allowed to zoom the page in or out.
There is a lot of code that needs to be redone.
Instead of being this painful, I highly recommend you to look into a framework like bootstrap or foundation. They both provide good template example to help you get started. Their media queries also work like a charm and they will help you cut lots of development time and some headache.
#head{
float:left;
width:100%;
}
#content_head{
display:table;
margin:0 auto;
}
#body{
float:left;
width:100%;
}
#content_body{
display:table;
margin:0 auto;
}
#footer{
float:left;
width:100%;
}
#content_footer{
display:table;
margin:0 auto;
}
If I was you, and don't want to do a complete overhaul, I would suggest you set:
<meta name="viewport" content="width=500px" />
And try fixing the things that float out of your 500px width (like the navigation).
This way, you don't have to do much work. The site is more or less a bit normal visible on a mobile. I studied your code a little, but it's a lot of working if you want to do it proper.
500px is somewhat ok for a mobile device, but you can tweak it to what you like, it isn't as nice as device-width but gives you a fair compromis between your pile of work to do and the general user experience. As long as you allow zooming (user scaling).
One other trick I suggest is to make the font a tiny bit bigger on mobile on some parts, like your brand nav. And form elements always minimal 16px so you don't get zooming on an iPhone when you focus a field.
#media all and (max-width: 767px) {
.brand-name-td{
font-size:1em;
}
input[type="text"],select,textarea{
font-size:16px;
}
}
Further, what's handy and improves the UX, there are some parts you just want to hide on a phone, use this:
#media all and (max-width: 767px) {
.hide-mobile{
display:none;
}
}
And just when you have some element you want to hide, add the class (divide by a space if you have more classes)
<td class="right-side-nav-container hide-mobile">...</td>
Regards
use diplay block and width to 100%, remove also float and max-width, min-width property.
Also you can simulate a mobile just by using a browser since you already have the viewport metadata. Just resize the width of the browser.
I picked up this handy little fix while browsing some random sites in firebug, it looks like what you're describing, why not give it a go and see if it works :P
$(function(){
// IPad/IPhone
var viewportmeta = document.querySelector && document.querySelector('meta[name="viewport"]'),
ua = navigator.userAgent,
gestureStart = function () {
viewportmeta.content = "width=device-width, minimum-scale=0.25, maximum-scale=1.6";
},
scaleFix = function () {
if (viewportmeta && /iPhone|iPad/.test(ua) && !/Opera Mini/.test(ua)) {
viewportmeta.content = "width=device-width, minimum-scale=1.0, maximum-scale=1.0";
document.addEventListener("gesturestart", gestureStart, false);
}
};
scaleFix();
});

Detect screen width with CSS Media Queries

I'm guessing that because you can do this with Media Queries:
#media (min-width:500px) { … }
That at some point or another, the CSS stylesheet must know what width the screen is, sans Javascript.
Is this the case?
You can use device-width which will test of the screen's width in px. That however is not entirely recommended. Use max-width and min-width (for the viewport) instead.
If you are trying to GET the screen width and use it (something like content: (device-width); of some sort, that's not possible. Stick with JavaScript.
Manual Reference
As the client browser's viewport changes size, the browser will repaint the visible area. At that point in time the browser will be checking if there are media query styles that are relevant for the new viewport.
The CSS doesn't really know what width the browser's viewport is, so much as the browser knows what CSS is applicable for a specific viewport.
Well...
#media(width:1024px){
p#id:after{
content:"1024px";
}
}
If the width of the viewport is 1024 pixels, this displays the text "1024px" after the designated <p> element. You could (hypothetically) put several thousands of such blocks of CSS to display the width of the viewport, for any reasonable value of its width. (Note that the text isn't selectable in some browsers.)
The more you know... (please don't actually do this)
In html ->
<meta name="viewport" content="width=device-width">
OR
In CSS ->
#viewport {
width: device-width;
}
Hope it helped.

Resources