Half-width inline-block elements cause strange position issues - html

I made a small form that has potential to take credit-card details, as part of the Daily UI challenges (#002). I haven't implemented any functionality, just design.
Here is the form I made: http://codepen.io/alanbuchanan/pen/vGZPBp
My questions are regarding the two half-width sections of the form - Expiry Date and CC Number.
Here is the relevant code - this targets the two divs that wrap the two form elements:
div {
display: inline-block;
box-sizing: border-box;
width: 45%;
}
I wrapped these two sections in their own divs so that I could have more control over their positioning. Is it possible to position these at half-width without these wrapper divs?
In the example they are taking up 45% width because at 50%, the second div overflows onto the next line.
I just want to give it 50% and have it take up half the space as it should. Or should it not?
Even at 45% width, you can see there is about 1px difference between the height of these two divs.
After inspecting with Chrome Dev Tools, I can't find the problem behind this.
Any answers to my questions or different approaches to the situation will be very useful.

In most cases a setup as the following code, could be a best practice when aiming for creation of inline-block columns.
.column-container {
font-size:0;
line-height:0;
}
.column-container .column {
display:inline-block;
vertical-align:top;
width:50%;
font-size:16px;
line-height:120%;
}
You might wonder, why does the container have zero font-size and line-height?
This is often used because some HTML code cotains indented code, like so:
<div class="column-container">
<div class="column">text</div>
As of this example, you can see that the container div contains spaces/tabs before the column div is programmed. These spaces/tabs are rendered as characters and so they will obey to whatever the css is telling the characters to do in that container div.

You can use flexbox.
Create a outer div having id as flexdiv which will contain both the div of expiry and CC number.
Then write following code:
#flexdiv
{
display: flex;
justify-content: space-between;
div{
display:inline-block;
box-sizing: border-box;
width:49%;
}
}
Codepen Example
Here is the guide for flexbox: https://css-tricks.com/snippets/css/a-guide-to-flexbox/

Pen: http://codepen.io/anon/pen/jqwJMg
Comments: just add font-size:0 to the form.
These are the changes I made:
.minicontainer {
width:50%;
}
form {
font-size:0;
}
When you add two element inline(50%-50%) you should make sure that the font-size is zero

Related

Creating a CSS assembly, floating divs left, right and bottom

I'm trying to create a "pattern" of divs that looks like this:
However, currently it looks more like this:
resulting in my page looking something like this:
In that final snip, everything is also pushed to the right. Ideally, I need the assembly to be centred. The Get Conditions button should also reside underneath the Print Runs textbox, as they both reside in the same div, and be centred beneath the two upper divs. The dropdown lists and radiobutton list are both where they should be.
I toyed with floating the bottom div, but the various things I tried mostly resulted in the lower div taking up more space between the two upper divs.
I have pasted the HTML and CSS in a JSFiddle, please bear in mind that it doesn't recognise ASP tools so doesn't give an accurate preview of what I'm trying to achieve.
https://jsfiddle.net/h4tr31gt/1/
This doesn't directly address your question of floats, but you can achieve the same result by using flexbox.
https://jsfiddle.net/gnw634gv/
.container {
background-color: lightblue;
height: 400px;
width: 100%;
display: flex;
flex-flow: row wrap;
}
.block-top {
width: 50%;
background-color: yellow;
height: 50%;
border: 1px solid black;
box-sizing: border-box;
}
<div class="container">
<div class="block-top">A</div>
<div class="block-top">B</div>
<div class="block-bottom">C</div>
</div>
As DaniP has suggested clearing floats would solve your issue. What float property does is removing your element from the actual page flow and aligning it according to your float value either right/left. So, when you try to add other element after the floated elements, it will occupy the page as if the floated elements doesn't exist. That is why you see that it is moved up. Also, floating the next element without clearing the previous elements floats will have the same result as without float. Hence, you need to clear the float using clear:both/right/left so that the surrounding of floated elements are cleared and you can align elements. You can check more on floats/clearfixes as some new things keep on arising every now and then. You might find it more clear.
add a class of clearfix to the parent div, like so:
<div class="clearfix"> </div>
then add the following style to your css:
.clearfix {
clear: both;
}
You can then reuse this anywhere else you are using floats.
https://jsfiddle.net/c3rLqce7/

Two divs in a row. left one grows to available space when right one changes size

I want to achieve an effect that will appear as the left div is growing to accommodate the available space after the right div changes size.
I've built an example of the html that I want to work with (divs are clickable):
http://jsbin.com/anaPIJe/3/edit?html,css,output
Best solution would modify the jsbin code to make it work the way I intend.
Thanks!
UPDATE My Fault, I didn't mention I want a CSS only solution
Try css3 flex box,
http://jsbin.com/anaPIJe/9/
#container {
display: flex;
...
#one {
flex: 1;
....
Try this.
#container {
display: table-row;
}
.inner {
display:table-cell;
}
Demo here.
I've changed the CSS and JavaScript slightly to make it work.
You can view the new code here: JSBin
I've substracted 2 of each width because of an invisible borders that is being placed around the divs

Make element fill horizontal line

This is a question similar to many that have been asked before. However, with all the previous questions, the necessary widths are known. For me, the widths are unknown.
If I have two columns (primary, secondary), how would I use css such that as primary expands and contracts, secondary fills the remaining horizontal space. I would like to achieve something like the split pane effect, where the location of the split is dictated by the size of primary.
It is imperative to understand that I do not know how many pixels or how much width primary will take up, primary's size will increase and decrease.
It could be:
|----Primary----|----------------------------Secondary---------------------------|
Or:
|-----Primary------|----------------------------Secondary------------------------|
Or even:
|-------------------------Primary------------------------|-------Secondary-------|
How would I do this using CSS? Is it even possible to make an element provisionally "greedy"?
Hmmm, if you're not adverse to using it, you could apply the display:table-cell CSS property to the columns, then use width:100% on the latter one. The HTML structure would look like this:
<div class="split-pane">
<div>
Left content
</div>
<div>
Right content
</div>
</div>
And the CSS:
.split-pane > div {
display:table-cell;
}
.split-pane > div:first-child {
white-space:nowrap;
}
.split-pane > div:last-child {
width:100%;
}
Here's a JSFiddle demonstration to show you what this achieves. Note how as you add more text in a line on the left, it'll push the boundary to the right as needed. (The white-space:nowrap; is there so that the content on the left doesn't wrap on every single word.) Be advised that this CSS will not be interpreted properly on older versions of IE, if that's of concern.
If this isn't what you were looking for, let me know and I'll be happy to help further!
It is correct you can't do this with pixels, however there are other ways to define width. I think you may want to try using % rather than px in your css.
If the content of the 'sencondary' div doesn't matter, you can make some css like this:
#primary { position: absolute;
z-index: 1; }
#secondary { position: absolute;
width: 100%;
z-index: 0; }
If there is content that needs to be moved dynamically, you can move the secondary div easily with jQuery. Here's a jsfiddle with the code: http://jsfiddle.net/LZJZU/5/

HTML/CSS: 3 columns, variable sides and fixed centered middle column

My problem is with the header. So I basically have 3 columns of divs. I want the middle one to have a constant width of 980px, and then I want the left of the header to extend to the end of the browser window with a blue background color. As for the right of the header, I want that to extend to the end of right side of the browser with a black background color. It kind off looks like this:
<------------------------------[blue][center header][black]---------------------------->
I've done my research and all I could find so far are two columns with a fixed left column with the right column filling up the rest of the space. I wonder how this can be applied to my problem?
Would it be like:
<div style="width:100%;">
<div style="display:table-cell; background-color:blue;"></div>
<div style="width: 980px;">my header</div>
<div style="display:table-cell; background-color:black;"></div>
</div>
Thank you!
A simple solution - basicaly using your exact stying, but putting another block in the central table-cell element, something like this span here:
<div class="wrapper">
<div class="left"></div>
<div class="center"><span>my header</span></div>
<div class="right"></div>
</div>
I moved all the inline style to a separate CSS block and used class selectors:
.wrapper {
display:table;
width:100%;
}
.left {
display:table-cell;
width:50%;
background-color:blue;
}
.right {
display:table-cell;
width:50%;
background-color:black;
}
.center {
display:table-cell;
}
.center span {
display:inline-block;
width:900px;
}
here is a jsfiddle
and here I made the center much narrower for a better illustration: jsfiddle
Hope this helps =)
Unfortunately there isn't a super smooth way of doing this that is also has wide cross compatibility support. There is a CSS spec for display called flex or flexbox which would do what you want beautifully and elegantly, but it has very limited support at the moment. Here is some resources on flexbox for your perusal...
http://css-tricks.com/old-flexbox-and-new-flexbox/
In the meantime, you can achieve the layout you want with some basic CSS jiggery-pokery that will get you what you want, but it requires absolute positioning your middle div.
Heres the JSFiddle: http://jsfiddle.net/CW5dW/
Here's the CSS:
.left {
width: 50%;
height: 300px;
float: left;
padding-right: 160px;
box-sizing: border-box;
background: red;
}
.right {
width: 50%;
height: 300px;
float: right;
padding-left: 160px;
box-sizing: border-box;
background: blue;
}
.middle {
position: absolute;
width: 300px;
height: 300px;
left: 50%;
padding: 10px;
margin-left: -150px;
box-sizing: border-box;
background: orange;
}
What is going on here you might ask?
Basically, we are taking the div with class middle and removing it from the flow of the document. This allows us to float our left div left, and our right div right, with widths of 50% in order to fluidly take up ALL space of the browser.
We then tell the middle div to take up 300px of space (in your case 980), and we tell it to go 50% of the total width of your browser from the left. This doesn't center it though, because its calculated from the left edge of your div. So we give it a negative margin space of half it's width, to sort of "move" that left edge to the center of the div.
Then, since we know the middle div has a width of 300px (in your case 980), we can then say that the left div should have some padding on its right edge greater than or equal to half the middle divs width, in my example that's 150px, and I added 10px more so text couldn't come right to the edge of the div, so 160px total. We do the same for the right div but for it's left side. This limits the content of those two divs from falling underneath our middle div.
This answer is not an "answer" as such - it's an extended comment to #Michael's post. I have, however, posted another answer - a jQuery solution.
Regarding #Michael's answer (which is a very tidy solution indeed) there is a tiny issue that if you remove your height declaration (which the OP undoubtedly will) then the backgrounds for the various columns become exposed - this method relies on the backgrounds all levelling out at their bottom edge in order to make the design coherent. If the OP's design doesn't have backgrounds behind the columns then this solution should be fine. If backgrounds are required (which they might be judging by the question wording) then it could be awkward. Two solutions to this...
a simple javascript that scans the page for column length, finds the longest, and matches all shorter ones to the maximum.
The other (and probably better) solution is to drop a background into your with the columns already on it (it only needs to be 1px high I guess) - just make sure the central white band is 980px wide and the side columns extend off a thousand or so pixels to accommodate even the largest of browsers
OK, here's my solution. This will present a "common or garden" three column fixed width layout to all users and then adjust it for users with javascript enabled (which, let's face it, is the vast majority of users). The benefits of this solution are that the layout will behave like any ordinary 3 solumn layout without the quirks you can experience from using more advanced CSS tweaks like absolute positioning and fixed heights.
Fiddle here... http://jsfiddle.net/vuary/
You should be able to see what's going on with the HTML and CSS... it's basic stuff. The jQuery is pretty straight forward too:
$(document).ready(function(){
// find the width of the browser window....
var docuWidth = $(window).width();
// find the width of the central column as set by the CSS...
// (you could hard code this as 980px if desired)
var centerWidth = $('#center').width();
// figure out how many pixels wide each side column should be...
sideColWidth = (docuWidth-centerWidth) / 2;
// then set the width of the side columns...
$('#left,#right').css({
width:sideColWidth+'px'
});
})
EDIT
Converted the jQuery to a function that is called when the document is ready, and again if the viewport is resized... just in case:
http://jsfiddle.net/aKeqf/

Horizontal line inline-block IE7

I would like to put 3 horizontal line in a row.
Does anyone know how to put an horizontal line displaying in inline-block in IE7 ?
Here is my CSS:
hr.small {
width: 28.9%;
margin-right: 6px;
display: inline-block;
vertical-align: top;
zoom: 1;
*display: inline;
height: 3px;
border: 0px;
color: #7c8690;
background-color: #7c8690;
}
but it doesnt works.
here is the JSFiddle Link: http://jsfiddle.net/sRuz3/6/
If anyone has a solution.
Thanks a lot.
Here you go: http://jsfiddle.net/eq3Z2/
It works in IE7 also.
Granted, they aren't HRs. They are DIVs. Trying to render the HR as an inline element
is tripping up IE7 but I don't know of a workaround.
Does it have to be inline-block? Can you not simply float them and set a height if necessary?
Edit - Example:
hr.small {
float:left;
width: 28.9%;
margin-right: 6px; /* Choice: Use border instead or halve the margin for IE7 and lowwer (double margin float bug). */
height: 3px;
background-color: #7c8690;
}
Edit again - Question:
Is this going in a fluid layout and how big is the container? You are setting a dynamic width but a fixed margin, this will cause issues in small scale and introduce unwanted white space to the far right in large scale. If it is a fixed area then consider using a fixed width.
It seems there's a solution if you can wrap the hrs in divs.
Set the div's to display:inline (we could use spans instead but hrs are not valid in spans)¹ and also give the divs hasLayout via zoom:1
See http://jsfiddle.net/YqKDJ/1/
¹ As an aside, there's a reason why hrs are not valid in spans and it's relevant here. An hr is not primarily a way of drawing a horizontal line - it has a specific semantic meaning of "Thematic break". It makes no sense to have two or more hr elements with no content betwwen them - there's nothing for the second thematic break to break from. If you want multiple horizontal lines for presentational purposes, you should use CSS to create them, along the lines of #Cynthia's answer.