Currently I have some large text on a page, and layout works fine for short text (~12-14 chars in length), but any more than that will overflow or wrap. This is undesirable, so I'd like the size to be reduced to fit the whole text.
I've looked into JS solutions like FitText and BigText, but they depend on a fixed width. Since I'm using Bootstrap, I don't have fixed widths.
Okay: http://tf2reputation.com/profile.php?id=76561197960947673
Not okay: http://tf2reputation.com/profile.php?id=76561198054504781
I'v also considered setting white-space: nowrap or truncating, but I'd prefer to show all the text, but smaller, if possible.
FitText does work with a fluid width.
From the github page :
Make sure your container has a width!
display: inline elements don't have a width. Use display: block OR display: inline-block+ a > specified width (i.e. width: 100%).
Bold is mine for emphasis.
Looking on the homepage for FitText also reveals that there are no fixed width units in sight.
I should also mention that there is not a native CSS technique to achieve this. The closest thing would possibly be viewport relative lengths but that doesnt solve your problem.
My additional opinion (danger beware) :
In my experience when you are confronted with a problem like this, its because you may be looking at things a little wrong from the design side, And if you require Javascript for your layout to stay intact, I do think that needs to be reconsidered. Nursing a design along is usually better than banging it into place with a crowbar.
End Opinion
You could try an iterative approach using javascript.
Put the contents into a span with white-space: nowrap.
If span is the span within, you can do something like this:
var maxWidth = span.parentNode.clientWidth;
var currentFont = parseInt(window.getComputedStyle(span).fontSize); // or max font size
while(span.offsetWidth > maxWidth) {
currentFont--;
span.style.fontSize = currentFont + "px";
}
This will continually decrement the font until the span fits within its parent.
If the allocated width changes as you resize the window, you may need to run this on window resize.
Related
NOTE: the motivation behind this post is solely to understand CSS better. CSS remains mostly voodoo to me (despite hours and hours and hours of studying it), and I'm certainly not looking for any more voodoo (i.e. more "workarounds" or "hacks"). I'm looking for insight into CSS.
I have found two approaches for centering a div within its container. (Throughout this post I'll call the div to be centered #inner-div.)
The first approach is based on giving #inner-div the spec margin:0px auto;; the second one consists in giving #inner-div the spec display:inline-block.
AFAICT, the margin:0px auto approach also requires explicitly setting the width of the div, as illustrated in this jsFiddle; the key bit of CSS is
#inner-div {
margin:0px auto;
width:100px;
}
(To see what happens if the width specification above is omitted, see this jsFiddle.)
Similarly, AFAICT, the display:inline-block also requires 1) giving the spec text-align:centered to the element containing #inner-div, and 2) preventing the extraneous bottom-margin that the display:inline-block entails for #inner-div (this could be achieved, e.g., by giving the spec vertical-align:top to #inner-div and, AFAICT, any additional descendants with display:inline or display:inline-block). See this jsFiddle, in particular the following bits of CSS:
#outer-div {
text-align:center;
}
#inner-div {
display:inline-block;
vertical-align:top;
}
I find both approaches problematic. The second approach is clearly problematic, since the display:inline-block gives the affected div text-like semantics, resulting in unexpected behavior (like the seemingly gratuitous bottom margin mentioned above).
The first approach, on the other hand, requires the specification of #inner-div's width. This precludes the possibility of having this width specified implicitly by the widths of the contents of #inner-div. I don't like this: I often need to center divs whose width is difficult for me to determine, even at run-time (e.g. this width may depend on font-metrics, or the way the flow works itself out within #inner-div, etc.). After all, as the jsFiddle's given in this post show, the browser already computes the height of the #inner-div based on its contents (IOW, one doesn't have to explicitly specify #inner-div's height for the browser to do the right thing). Why can't the browser also compute #inner-div's width?
It seems to me that any reasonable layout system would allow one to say to the browser: "figure out the width of this div, based on the width of its contents, and center it within its container".
My question has two parts:
I'm looking for a well-informed confirmation that CSS really does not provide any way to direct the browser to compute the width of a div (based on its contents) and then center said div within its containing element; and
if the answer to the last question is "yes", is this so merely due to poor design on the part of the creators of CSS, or is there a good reason for CSS not to support this natural (to me at least) functionality?
Note: these are difficult questions; the second, in particular, requires not only a a command of the CSS standard, but also an understanding of the design of CSS itself: a pretty tall order!
Without a given width to work with, how would the browser know how to calculate the flow wrapping? It would be nice to tell the browser to 'make it look good', but they just aren't that smart. I feel your pain though; a fixed minimum width with a on-overflow-expand would make life easier.
How about setting the width as a percentage of the page width, or setting it dynamically with script?
I agree setting the div to a inline-block/table-cell/whatever introduces more trouble than it is worth.
BTW "margin: auto;" is enough, "margin:0px auto;" seems contradictory.
This probably was answered somewhere, but I can't find it :s
My question is about dynamic resizing of divs based in percentages.
Please look at code example below for the examples and possible solutions I made.
I ask if there is a better way to do resizing?
More detailed explanation:
Say I am writing a plugin that people can insert in their pages. (Imagine login form).
I go ahead and design the plugin's divs. I use media queries to achieve desired look for different devices. I work on a div straight inside of a 'body' element.
I use percentages for design (I like percentages). Say I set div to 80% width.
Now I give this plugin to the user. User goes ahead and puts the plugin's div inside of another
div that is 100px in width. Now everything looks awful. (80% of 100px is not a lot [80px]).
And of course I want user to put my plugin inside of whatever small-width divs that he have.
The solutions I saw so far to this problem was to create a holder div of certain width - say hardcode 300px. (ex - jQuery UI's Datepicker div; Meteor's login widget div). And then code to it always knowing the 300px width that I set before is not going to change.
But I don't know how good of a solution this is.
Moreover if I decide to go with hard-coding width, my plugin would need width of ~ 1000px. Because I want div to resize with media queries.
And if I go with hard-coding width (say holder div of 1000px width) and put it on a page, the page will have horizontal scrolling. And you cannot simply hide holder div (parent div) and have child to show at the same time. So this requires setting position:relative for holder (parent) div, putting it outside of window, and use same for child div - position:relative with same offset in opposite direction of parent offset.
I hope I am being clear so far and have not confused you!
A code example to illustrate what I am talking about:
http://jsbin.com/ifawez/18/edit
#cimmanon's comment cleared things out for me.
The problem is with lack of HTML/CSS "tools" available at the moment. Since responsiveness came into play fairly recently there are not a lot of CSS-native tools to accommodate changes in dimensions.
For instance media-queries exclusively work with width of window/document and not of other elements such as divs.
The solution I currently employ is using Javascript to determine width of a div and resize accordingly.
What I resize is the number of columns I want to display (I use Multi-Column module as suggested by cimmanon) which is pretty stable on webkit browsers. Since it is all done in Javascript (and jQuery's Sizzle) I keep an array of sizes like so:
var widthArray = [
{min:0, max:250, columns:1, secondary:false},
{min:251, max:350, columns:1, secondary:true },
{min:351, max:479, columns:1, secondary:true },
//more div sizes
];
// more code here
$(element).css({
"column-count": object.columns,
"-moz-column-count": object.columns,
"-webkit-column-count": object.columns
});
This is sort of like media-queries, but allows to work with width of html elements, not screen size alone.
Additionally I follow the way jQuery UI displays its components: using position relative/absolute.
.outer_div {
position: relative;
}
.inner_div_with_elements {
position: absolute;
z-index: 1010;
width: 99%;
float: left;
overflow: hidden;
...
}
.inner_components_displayable {
position: relative;
display: block;
}
.inner_components_hidden {
display: none;
}
So in Summary:
Media queries alone work with size of screen, and resizing of any inner element can be done in percentages to the screen size. They can be of huge help, but you turn into making your components work either with percentages based off screen, or specifying something like min-height and !important (as suggested by #Octavian)
Javascript manipulation of elements is currently easier, but is a costlier alternative (jQuery SIzzle is pretty slow)
A lot of libraries (ex. jQuery UI) use Javascript together with position relative/absolute to make sure their components/plug-ins will work nicely on all users' screen sizes.
I ended up combining position with javascript to emulate media-queries and multi-column design at the same time for responsiveness.
Thanks everyone who participated!
If I am reading this correctly, the main issue here is that it can potentially become too small based on where the code is located.
So why not just add a min-width property with !important? That way you can still base the size off of the parent container, but be sure that it doesn't get too small and ugly.
Potentially, you could even have a script to base the width off of the parent div and the min-width off of the screen size.
I have a %-based grid with a fixed-width (for the moment). The code is based off of this css-tricks article: http://css-tricks.com/dont-overthink-it-grids/
Works great until I have a column that has multiple responsive images in it that are the same size and need to be stacked next to each other (floated). Because of padding issues and what-not, I can not get all three images to come out the same width and height, despite the fact that they start that way. The last one is always taller. Here is a codepen showing the issue: http://codepen.io/joshmath/pen/dEuIv
Any help with this would be really appreciated. I've run into this issue before and always just end up hacking my way through it on a case-by-case basis. Thanks!
For whatever reason, if you remove the padding-right: 0 style from the last element, it fixes the issue.
It looks like you're trying to add spacing between the elements using padding. What I tried instead using the Chrome dev tools was to use a margin instead of padding, and then slightly reducing the width of your elements to around 29.5%. That seemed to work.
just add the following to your css. set the size to whatever you like and all images within your grid will remain that size, if they need to grow / shrink use height/width percents instead.
.grid img
{
width: 350px;
height: 400px;
}
I am working on removing tables from my site, and just learning the div tricks involved. My home page currently has a centered table nested in another table. Removing the outer table was a bit tricky for someone just learning non-table methods, but it's done.
My problem is, the inner table is super-easy to center ("margin:0 auto" in the CSS), but its div equivalent is not. The div will center if I specify an absolute width (such as 640px), but since I'm designing with the user's font size (not something I specify), I don't know how wide it will actually be for a given user.
I've simplified the home page and have it online (test.html and HoH.css Here is an overview image of test.html.
Sorry for all the links. But with a floaty thing inside another floaty thing, I don't know what is relevant. The file test.html contains 63 lines of formatted HTML. The 640px hr is there for reference only; it will not be part of the final page.
PS: I'm removing the tables because when I asked for site reviews, the first comment almost everyone had was, "get rid of the damn tables".
Probably you shouldn't worry about users font size because all modern browsers zoom whole page, not only font size, and everybody will be happy with your fixed width.
Also you can use EM values instead of PX, 1em = font size in px. You can change 640px to 40em if you have 16px font size. If someone have for example twice bigger font, he will get twice wider block.
And if you want css-solution for unknown width block centering, you can use inline-block and text-align:center: http://jsfiddle.net/rBc4T/
use CSS and jQuery -
css -
#divID{ left:50%;}
jQuery -
(function(){
var marginLeft = $('#divID').width();
$('#divID').css('marginLeft','-'+ marginLeft /2 +'px');
});
I am pretty new to CSS, and would like to know if there is/are some sort of rule/rules of thumb for determining when to use different units to define layouts. Currently I have everything defined in %, because I thought that'd be good for window resizing. That is not the case, text starts to overflow, images get screwed around and so on.
Any help will be appreceiated.
Typically, I use the following
Layouts - Pixel (Unless something needs to be a % width/height)
Fonts - Pixel (Sometimes % for accessibility, but it is a nightmare to maintain)
Generally speaking, you can use pixels most of the time. The font issue is a more complex one. For instance, if you want the "increase font-size" features to work within a browser without resizing the rest of the page, you need to use %'s. However, when using % font sizes, a child element always inherits the parents font-size, so you get the following:
body { font-size:87%; }
h1 { font-size:87%; }
This will mean that the h1 is actually 87% of 87%. This can be quite annoying. As you end up with percentages > 100%. It gets very thick fast, and is best avoided.
I'm not sure if em's work in the same way, I've never looked into them in great detail.
Using percentages to have a layout work in different size viewports is a very advanced technique, and is often done dynamically using javascript. Until you are more familiar with CSS, and can look at working percentage based layouts and understand enough to replicate it, you are better sticking to PX.
If you are going the javascript route it is really quite simple. For a start use jQuery as it makes resizing your layout a breeze compared to trying to do it with native javascript. Then $(window).height(); gives you the height of the viewport; $(window).width(); gives you the width. You set a default px width for your container, and then use percentages for all other block level elements (containers, within the container, sidebar, main etc) and do this:
function percentagize() {
var height = $(window).height()-100;
var width = $(window).width()-20;
$("div#container").css({
'height' : height+'px',
'width' : width+'px',
'margin': '0 auto'
});
}
$(document).ready(function() {
percentagize();
$(window).bind('resize','percentagize');
})
This should give you an idea: http://w3schools.com/cssref/css_units.asp
% is not explained properly on that page, but it means x% of the containing block.
You should use ems for fonts so that they are always relatively sized... by default they are 1 em or 16px... you can set play with this by setting body { font-size: 75% } which makes 1em the equivalent of 12px The PxtoEm calculator is great. From here you can do things like
h1 { font-size: 3em }
p { font-size: 1em }
now no matter what you set that body font size to the h1 tag will always be 3 times larger than a paragraph. It gives more flexibility and keeps yout type hierachy proportional.
For layouts it really depends on the layout type... for the classic fixed with central column then use pixels.... for fluid or adaptive layouts then use percentages (or a mix of fixed width, i.e. left hand nav bar andpercentages)
Use em as much as possible, since this is the most maintainable. The em unit depends on the font size of the current element, so if you change the base font size, em-units scale along.
Use px in screen style sheets when you need a fixed size. Typically you would specify the size of the base font in pixels. Image sizes should also be specified in px, since an image should not scale up or down just because you change a font - it will just make the image blurry. Also border thicknesses should probably be specified in pixels, since you don't want it to depend on font sizes.
Use pt, pc, in, cm, mm only in print media style sheets. You probably wouldn't to mix metric and imperial in the same style sheet, so decide on either in or cm/mm.
% is tricky since it means something different depending on the property. For font-sizes, 100% = 1em, so its just a matter of preference if you like % or em. (I prefer em for font sizes, since % have different meaning in other contexts.) It is not affected by window scaling though. The font size doesn't scale with the window size, and neither does em or % units.
For width and height on boxes, % refers to percent of the size of the parent box, which for the root element is depending on the window size. This is much less useful than it sounds! For example if you have a flow of text without any specified width, the lines will become too long to read comfortably. If you specify the width of the text box in em's you can give it a nice readable line-length, on any screen. But if you specify the width in % it will scale with the size of the window, which means it can still be too long on some screens and to short on others. Scaling with the window size sounds good in theory, but is rarely what you want.