Vertical aligning in CSS? - javascript

So I know all about the problems with vertical-align: middle; and the different methods people have used to vertical align elements in CSS. But I haven't found one that works for what I need it to work for.
Basically my page has just one <div> on it, which I want positioned in the center of the page, both horizontally and vertically. Obviously the horizontal part is easy, but I'm getting hung up on the vertical part. My problem is that the height of the <div> is unknown; the content changes, so I can't specify a height for it.
Anyone have any tips for me? I'm willing to use JavaScript if necessary. Thanks!

Long story short, you need two divs to get CSS-only vertical centering.
With Javascript, you can do it with a single div, though.

As you said you don't mind using JS, here it is... (I generally never fallback to a JS solution, but if you're cool with it, then so am I)
If your CSS is
#element {
position: absolute;
top: 50%;
}
Then you could use my friend jQuery
$(document).ready(function() {
var height = $('#element').height();
$('#element').css({marginTop: '-' + (height / 2) + 'px'})
{);
Note, this is untested, but should be a start. Hopefully the height / 2 will work as expected, if not, try using parseInt();

Related

Move text while one word is being animated

I'm working on an animating text element.
The element changes one work with animation. Much like in this example.
http://www.thepetedesign.com/demos/jquery_super_simple_text_rotator_demo.html
The thing is I don't like that when I change one word, the other words around it shift abruptly. I'm trying to use an effect where the other words that move around shift in a nice way. Like in this example.
http://www.thepetedesign.com/demos/jquery_super_simple_text_rotator_demo.html
Does anyone know how to do this? or link me to a relevant solution?
I'm using HTML, CSS, and JS
There may be other ways of doing it but the most consistent cross browser way of doing it that I can think of is this. This is some guidance but code samples would be helpful.
You'll need to have the animated word wrapped in an extra span. Then you'll want to define the width of the outer span to be the width of the inner span before animation. You can do this with CSS if you know what the width will be or you can do it dynamically like this:
$(outerSelector).width( $(innerSelector).width() + 'px');
Animate the text then animate the width change:
$(outerSelector).animate({width: $(innerSelector).width() +'px'}, 500);
This really only works for making it smaller. You can use this method for making the word bigger but you need to know the final width of the word first. Then you could simply have one span and do this:
$(selector).animate({width:newWidth}, 500);
If you're not worried about cross browser compatibility or if you can assume that everyone using the site will have a CSS 3 enabled browser then you can do it with CSS:
selector {
transition: width 0.5s;
}
Then you for shrinking text you would need to again set the outer span width like above, but after the animation of the text you could simply do this:
$(outerSelector).width( $(innerSelector).width() + 'px');
This has the same problem with needing to know that width in advance for transitioning to longer text. You could find out the width using another span with identical text.
.copy {
position: absolute;
left: -100%;
}
Then you could get the width of the copied version and use that as the new width for animation.

centering contents of topLeft, topRight, bottomLeft and bottomRight ids

I'm trying to create a responsive site (resize the browser window to see the changes), but I'm unable to center these checkered divs.
http://arunmahendrakar.com/ktw/play.html
The divs are dynamically created and appended to one of the four 'container' divs (#topLeft, #topRight, #bottomLeft and #bottomRight).
I have tried using margin-left:auto; and margin-right:auto on various elements, but that did not help.
Please help me horizontally center the #topLeft, #topRight, #bottomLeft and #bottomRight divs. I prefer a pure CSS solution, but if it is not do-able, I'm ok with a js tweak as well.
There are a whole bunch of different way to do this with some tweaking to the way you build that structure. Here's what I'd do:
First, size things a bit more normally; make the quadrants (#topLeft for example) width: 100% and the individual square sizes padding: 5%. This will give the squares the same size as they have currently, but the 100% width ensures that things are actually centered where you want them to be. At 200% the "center" of a quadrant will be off by 50%.
Next, instead of using float and clear, use display: inline-block on the squares. This will have them all running together on a line; your Javascript can manually break them up by inserting a <br> after every 5 squares. You'll no longer need to add the clearBoth class once you've done this.
At this point, you should have almost exactly what you want. There will, however, be some extra spacing between each row of squares. This is due to whitespace in the HTML, and to get rid of it, just set make sure the quadrants (again, #topLeft for example) have font-size: 0 set.
That ought to do it!
Explanation
It's really pretty simple: display: inline-block obeys text align. By creating your checkerboards out of inline-block elements instead of floats, you can control which side they align to by just changing out text-align.
All the other stuff is just some necessary cleanup work to make this technique work nicely.

Responsive two column panel layout in priority order

I've been working on a way to display panels on a homepage, the page is responsive and would start off with all the panels being 100% wide and stacking and then at a certain breakpoint the panels would split into two columns.
My work in progress is here http://codepen.io/charge-valtech/pen/aIEGf
This works nicely with the panels flowing in priority order from left to right. However the problem is this page would need to be dynamic, so any of the panels could be "switched off". So if you got rid of the third panel, because of the way floats work the fourth panel tries to go over to the right, even though float: left has been specified.
Using clearing would keep it to the left, but then there would be a gap where the third panel was...
I hope this makes some sense and was just interested in how other people might approach the problem. I'm thinking JavaScript might be the way to go but wouldn't really know how to go about detecting if there's white space available.
Cheers
I thought I'd share my solution for this, since masonry was a bit overkill for this and didn't work as cleanly as I would've liked.
I have two classes in my css left-widget and right-widget, these are then set their widths and floats using a grid system, which essentially gives them float left and float right and 49.something% width.
By default I give all the widgets the left-widget class, and then with some jquery I do this:
$('.left-widget').each(function (index, value) {
var widgetPosition = $(this).position().left;
if (widgetPosition >= 30) {
$(this).removeClass('left-widget').addClass('right-widget');
}
});
$('.right-widget').each(function (index, value) {
var widgetPosition = $(this).position().left;
if (widgetPosition <= 30) {
$(this).removeClass('right-widget').addClass('left-widget');
}
});
This now does exactly what I wanted it to do, sticking the widgets to the right if they fit.
Use CSS media queries:
#media (max-width: 1000px) {
#box-js {display:none}
}
The CSS rule for #box-js will only be executed when the screen with is below 1000px.

Is it okay to rely on javascript for menu layout?

I have a website template where I do not know the number of menu items or the size of the menu items that will be required. The js below works exactly the way I want it to, however this is the most js I've every written. Are there any disadvantages or potential problems with this method that I'm not aware of because I'm a js beginner? I'm currently manually setting the padding for each site. Thank you!
var width_of_text = 0;
var number_of_li = 0;
// measure the width of each <li> and add it to the total with, increment li counter
$('li').each(function() {
width_of_text += $(this).width();
number_of_li++;
});
// calculate the space between <li>'s so the space is equal
var padding = Math.floor((900 - width_of_text)/(number_of_li - 1));
// add the padding the all but the first <li>
$('li').each(function(index) {
if (index !== 0)
{
$(this).css("padding-left", padding);
}
});
You can do this hackily in CSS, using display: inline-block, and text-align: justify
<ul>
<li>thing</li>
<li>thing2</li>
<li>thing3</li>
<li>thing4</li>
<li class="hack"></li>
</ul>
And then:
ul { text-align: justify }
li { display: inline-block }
li.hack { width: 100% } /* force the justified text to wrap */
Demo
​
Yes, there are disadvantages of using JS for formatting.
It is strongly recommended to avoid using JS for formatting and positioning, use CSS whenever possible.
Javascript is interpreted and run very differently from browser to browser, from OS to OS, from OS/browser version to version.
CSS rendering is a native browser engine function and its rendering priority is higher than that of JS.
CSS rendering is much more speedy than JS.
Etc.
What you are doing now I would never suggest doing. IMHO, this is a very wrong approach. JS is absolutely definetely misused in this case. You have to use CSS for this task, and I would suggest posting a question about how to use CSS correctly for this task.
I would suggest having a default spacing between them in a way that would not push them out of their container. The extra javascript to enable them to space equally should be an enhancement only.
I think the answer to your question is, if it works, then it works (and will continue to work), but that doesn't mean that this is the best way to handle it. If you *care about the best way, then investigate how to improve your approach using mostly (or even exclusively) CSS. If you're just looking to get the job done, and it's working, then you're good to go.
Depending on your site visitors, there will be around 3% who visit you with JS disabled. And you want the site to work for them to. Maybe not the unnessecary parts of the site but you want the critical parts to work. Navigation is one of the most important parts of a website.
Make sure the navigation works without JS (doesn't have to be as fancy as with JS) and then you could make some improvements with JS.
You don't need JavaScript as long as you can rely on a CSS algorithm that adapt width to its content: the table layout algorithm :)
See http://jsfiddle.net/r9yrM/1/ from my previous answer for examples.
Don't forget to have a minimum padding on each "cell", text stuck to a border isn't very readable (and ugly). You'll also probably want text-align: center on cells (last CSS rule).
With JS, you could decide of a maximum number of tabs (or a minimum "reasonable" width) and above (below) that number, add a class on the parent that will trigger each tab to render as float: left and block and not table-cell anymore. Then it'll occupy 2 or more lines (like the extension Tab Mix Plus on Firefox)
Note: there're at least 2 algorithms for table: with and without table-layout: fixed, depending on freedom left to the browser when adapting.
Note on your jQuery code above: "each li except the first" can be expressed by $('li + li') (the first one isn't preceded by a li)

HTML/Javascript - Inconsistent positioning

I'm in the process of designing this site http://www.parisgaa.org/parisgaels and have a problem.
The image slider on the homepage messes up sometimes. Most of the time it works and looks fine, but other times its positioning seems to get messed up and it appears underneath the content that should be below it (i.e. with that content overlapping the image). You should be able to replicate this in Chrome - just refresh a couple of times.
I'd appreciate any help at all.
You are going to have to edit a line in the slider file
js/slider.js
.wrap('<div class="bx-window" style="width:'+childrenMaxWidth+'px; height:'+wrapperHeight+'px; position:relative; overflow:hidden;"></div>')
.css({
height: '999999px',
position: 'relative',
top: '-'+(origTop)+'px'
});
Within his you will need to define a height that works for your images like
.wrap('<div class="bx-window" style="width:'+childrenMaxWidth+'px; height:400px; position:relative; overflow:hidden;"></div>')
.css({
height: '999999px',
position: 'relative',
top: '-'+(origTop)+'px'
});
The problem isn't your implementation rather the script you are using. You could try using a different script but hopefully this adjustment will do the trick for you!
It looks like it might be a problem with whatever jQuery plugin you're using for the image slider. The height of the .bx-window element isn't being evaluated correctly for some reason (for me it's in the ballpark of 20-30px instead of 420px). I would try out a different slider (there's ton's of jQuery image sliders out there, just google it), but if that's not an option, it would probably be fairly trivial to fix it yourself in their code. Good luck!
Try making the image slider position relative:
style = "position:relative;"

Categories

Resources