Simple questions: CSS page layout - html

Bear with me, I will now post a dumb question. Being an amateur at web-design, I don't fully comprehend CSS. Specifically, how to arrange objects in the horizontal plane.
Right now, the dashed <'p>' box is below the empty <'div>' box. I want to put them next to each other, horizontally. How to go about it?
<html><head><style>
#div1
{width:400px; height:75px;border:4px solid;}
</style></head><body>
<div id="div1"></div>
<p style="border-style:dashed;border-width:2px;height:30px;width:396px;text-align:center;">Move me</p>
</body></html>

Don't feel bad that you haven't grasped CSS layout yet – it has been a long time coming in terms of standards support, so most methods today use slightly hacky methods to acheive it, and it's not always self-evident how they work or why.
Blocks by default stack vertically, so you want to change the flow to run horizontally for a specific part.
The proper "modern CSS way" would be to use flexbox, which is specifically a layout tool for these types of situations (and more). The caveat is browser support – IE10 and above, but otherwise most every browser supports it.
To lay something out horizontally with flexbox, you'd tell the parent to become a horizontally oriented container. In your case, it might therefore be a good idea to wrap the two elements in another element:
<div class="wrapper">
<div id="div1"></div>
<p>Move me</p>
</div>
You then tell the wrapper to become a "flex container", where the default mode is to flow boxes horizontally rather than vertically:
.wrapper {
display: flex;
}
There have historically been a couple of experimental flexbox implementations with different syntax, so that's something to be aware of too (see example later).
The next step would be to size the boxes, if you want them to be sized other than according to content – that would be the next step in learning about flexbox. :-)
The first thing you will need to know is that they will still react to the width property in this situation, and otherwise stretch to become equally tall.
If you want wider browser support, you can combine flexbox with other methods that aren't as fit for this exact purpose but still work – floats or inline block comes to mind. The nice thing about flexbox is that it ignores the display mode and float properties of its children. This means that we can combine old and new techniques.
Floats are originally intended to position images or other figures to the right or left in blocks of text, for example, but can be used to create whole layouts with a bit of work. They have some complex behaviors that take a while to grasp. For example, since floats stick out of their container vertically by default, you usually need to add something that makes the wrapper enclose the floats – the easiest way is probably to apply overflow: hidden to the wrapper.
Inline blocks are basically to allow block level elements in the flow of text, but since text flows horizontally (in English, at least) you can co-opt them to create full horizontal layouts as well. The downside is that any whitespace (including linebreaks) in the HTML source will create whitespace between the horizontal items.
If you go the float route, the example code could look something like this:
.wrapper {
/* various flexbox syntaxes, old */
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
/* modern flexbox syntax */
display: flex;
overflow: hidden; /* contain floats */
}
.wrapper p,
#div1 {
float: left; /* will be ignored by modern browsers */
}

You can set display (inline, or inline-block)
An inline element does not start on a new line and only takes up as
much width as necessary.
CSS
#div1, p{
display: inline-block;
}
DEMO HERE

You should set display to inline-block for them. Check this fiddle.
Also you may set them vertical-align: top (look at fiddle again) and they'll be aligned to top.
Right now <p> a little bit below <div>. Set margin for p to 0 for change it.

Use float:left for the first div
{width:400px; float:left; height:75px;border:4px solid;}

The way I personally would do this is to add a wrapper to both of these elements and align them textually with text-align
<div id="wrapper">
<div id="div1"></div>
<p style="border-style:dashed;border-width:2px;height:30px;width:396px;text- align:center;">Move me</p>
</div>
and then add some CSS to that wrapper:
#wrapper {
text-align:center;
}

Related

Floated element "steals" width from a following block element inside a display:table container

I have a div that's "floated" to the centre with display:table; margin:auto; (green box)
Inside this, I have a float:left element (red box, which is not always present), then a number of display:block; "lines" (lime boxes). The application is poetry formatting with drop capitals and reverse indentation:
https://jsfiddle.net/nktj94gd/2/
The problem is that the floated "L" is "stealing" its own width from the lime blocks, rather than allowing the outer block (green) to expand to prevent the lime lines wrapping when they do not have to.
I'd really like to avoid having lines wrap when they don't have to, but I cannot set the width of the overall box (it could be from a few em to 100%) .Is there a way to achieve this?
I would use an extra wrapper inside that I make slightly bigger considering the width of L
.outer {
display: table;
margin: auto;
overflow:auto;
outline: 1px solid green;
}
.outer > div {
width:calc(100% + 2.8em); /* 2.8em is an approximation of L width */
transform:translateX(-1.4em); /* rectify the centring */
}
.dropcap {
float: left;
}
.dropcap-inner {
font-size: 4em;
line-height: 1em;
margin-right: 1em;
border: 1px solid red;
}
.line {
display: block;
text-indent: -4em;
margin-left: 4em;
border: 1px solid lime;
}
<div class="outer">
<div>
<span class="dropcap"><span class="dropcap-inner">L</span></span>
<span class="line">orem ipusm dolor sit amet</span>
<span class="line">Lorem ipusm dolor sit amet dddd</span>
</div>
</div>
you probably found some more practical solution to this a year ago, but this is a fairly obscure problem I ran into while also styling poetry, so I figured I'd post my solution in case anyone else needs it :) Hope your poem project worked out, OP!
I think probably most people use <br /> and ::first-letter or something and thus never run into the problem. It's ultimately just a problem of how to preserve intended whitespace (linebreaks mainly) with a pretty dropcap, which is niche, but falls apart quick if you're designing responsively and avoiding hard breaks. (I was using whitespace: pre because it had indented stanzas) ¯\_(ツ)_/¯
How to fix OP's issue: table CSS and wrappers (responsive, markup-dependent), see: https://jsfiddle.net/eja5mnuk/
Stick the spans and the float in a container div
Change display: block on the spans to display: table-row; since your outer is display: table, and you don't impose widths anywhere here, the 'table' will simply expand to accommodate both the float and the linebox
Optionally, display: table-caption on an inner part of the dropcap (not truly necessary, but in OP's code so why not: https://jsfiddle.net/thn2x5zc/)
Everything is integrated into a table formatting context, but we aren't getting unwanted collapse that messes up sizing
This is responsive and doesn't care what your drop cap is. It runs into overflow issues if the drop cap and poem are both too big, you can shove whatever behaviour you want on this bad case if you want (like overflow: hidden on the dropcap, controlling their whitespace/widths, etc....)
It does care about your container structure and margin collapse a lot, so if your code were different, you'd need a different display value, likely something putting table-row/table-cell on a block.
Of course this does have quirks relating to how browsers treat table elements by default, though - mainly auto-collapsed borders, like in a <table>.
Method #2: ::first-letter pseudo-selector, white-space: pre, margin/padding etc. (things other people might use) see: https://jsfiddle.net/3oghpj0w/
These things are all very janky/contradictory secretly, but since ::first-letter is a pretty standard way to style drop caps, and marking up/styling your lines individually may be inconvenient, it is how I ran into the problem lol.
If it's ::first-letter, we're using a block-level element to hold the poem text. The most basic way is just to apply width: min-content; to that block's container to get it to sort of take away the float's contribution (since it's larger). Then you can add padding-right to that container to re-accommodate borders, margins, etc. (If the margin between the drop cap and poem is 3em, add 3em back to the right.)
Fixes of this style do not re-integrate the float with the poem, so the poem will still have overflow issues. But it's sufficient for fixing simple alignment problems :)
Some notes
The float contributes size to the block e.g. via its margins - floated margins don't collapse, generally, which is part of our problem here. But the container won't expand for things out of flow, and thus the float pushes its siblings into overflow (poetry is highly sensitive to wrapping and whitespace)
Ultimately, most ways the browser can calculate the size of text wrappers ignore the float (it's out of flow); everything skews towards occupying space along the inline and block axis (horizontal/vertical, here), based on everything's sizing, margins, wrapping, and other inline/block contexts, ref: https://developer.mozilla.org/en-US/docs/Web/CSS/display
Tables are the ancestors of most responsive text framing
Sorry this is so long! A lot of conventional fixes break when you care about the shape of the whitespace and can't treat text as a block, which makes a lot of search results very inapplicable.

What is a better method, float or display-inline? [duplicate]

This question already has answers here:
float:left; vs display:inline; vs display:inline-block; vs display:table-cell;
(6 answers)
Closed 8 years ago.
In this example I would be using 2 DIVs
<div>
<div class="element"></div>
<div class="element"></div>
</div>
With CSS
.element { float: left; }
Okay so the above is one method of displaying the blocks as inline. I recently came across another method:
<div>
<div class="element"></div>
<div class="element"></div>
</div>
.element { display: inline-block; }
Now the above also displays the blocks as inline.
Although, The First method would have another thing to worry about, i.e. When you use float, it disturbs the normal flow of the content.
So I wanted to know, Which of the above method is the best way to achieve an inline display?
And if its the second method, then does that mean I should not use the first one?
display:inline-block is the best way but keep in mind that when you are using display:inline-block, there would be some cross browser issues, the divs may display a little bit differently in various browsers such as some maybe aligned top while in other browsers it may be alignment bottom. A simple way to fix this is by setting the vertical-alignment
Benefit of using display:inline-block is that you can have your divs in the centre. If you want too of your divs to be displayed in the centre of the pages then this can be achieve by using display:inline-block and in the parent div you have to add text-align:centre. This cannot be achieved with floating and you can save those extra padding from the side which you will add to make them appear in the center.
Float:left has its benefits as well and should be used more then inline block, whenever and wherever needed
"display: inline-block;" is best method to achieve inline display accepted.
Here is a good resource that covers this topic: http://foohack.com/2007/11/cross-browser-support-for-inline-block-styling/
Basically IE has a trigger called "hasLayout". Triggering this will allow you to use display:inline-block on a block level element (by default IE only allows inline-block on native inline elements).
Additionally older version of Firefox didn't support inline-block either, but had an "inline-stack" value (moz-inline-stack).
As per my knowledge, the best way to get a cross-browser "display:inline-block"
display:-moz-inline-stack;
display:inline-block;
zoom:1;
*display:inline;
but "float:left" is also useful when you don't want blocks and you want it to align left
You can use both if you give display: inline-block,
the div will be placed next to each other,
And vice versa for a block element if we use float: left,
until we specify width it does not place next to each other.

How to make div boxes with floats have the same height with dynamic content

In tables, if you have a row, that row is the same height and all cells in the row grow and shrink with dynamic content. (If one cell has a ton of text and the other cells not much they are all the same height, letting you make columns and rows).
With the popularity of div float layouts using tables is often frowned upon. However how do I duplicate this and other functionality and benefits of a table while still keeping the display set to block for the benefits of a block, cross browser?
I've seen many hacks but they always seem to be too complicated, interfere with each other, or take tweaking. I am looking for a standard reliable method for the following:
Make div boxes the same height across a row with a wrapping container
<style>
.cell { float:left; }
</style>
<div class="row">
<div class="cell">Content 1 with more width</div>
<div class="cell">Content 2<br>with<br>more<br>height<br>Content 2<br>Content 2<br></div>
<div class="cell">Content 3</div>
</div>
In this case all div's of class "cell" will have the same height, and not be fixed height at all and be floated and will stay that way for dynamic content of any size.
Vertically center content
In this case using the example above, all content would be vertically aligned to the middle, for dynamic content of any size.
Make div's of class "cell" share a common width that is based on the wrapper "row"
In a table when you specify width as 100% or fixed width the cells will automatically try to all be the same width, unless an image or block like item prohibits this. How can this be achieved with floating divs? As if you say, float all "cell" to the left, you can specify a min width or a fixed width, but I know of no way to make them share a common width that is dynamic, like a table. In floated divs by themselves they shrink to the size of the content.
How to avoid content pushing against the container/wrapper "row" and treat it as if it were just a block
For whatever reason when a floating div is inside a wrapper you can get odd behavior where content will "stick" to the wrapper as if were floating too. Even sometimes when using a <br style="clear:both"> at the end I had this happen.
If you could answer all these questions about floating divs for me it is most appreciated. Please don't tell me to break this into separate questions as they are all related to the same thing. Please don't tell me this would be better asked somewhere else. If however you wish to be helpful great :)
If the solution is using display:table-cell alone, I've tried this, it makes the divs not behave as a block, shrinking it, the background shrinks to the content too, and in other ways it does not behave as a block. Also some versions of IE do not support this and I am looking for a cross browser solution. Thank you.
If you want your div elements to behave like table cells, you can style them that way:
.row {
display: table;
width: 100%;
}
.cell {
display: table-cell;
width: 33.33%;
vertical-align: middle;
text-align: center;
}​
This does not rely on setting a height or min-height on the .cell elements, so the height will remain flexible.
--- jsFiddle DEMO ---
You may apply the CSS like this;
.row{
height: 200px;
}
.cell{
display:block;
float:left;
height:100%;
}
Here is a working Live Demo.
and Here is a workaround to distribute the columns also.
Hope this helps
Note: DO NOT add percentage attribute to child divs to fill parent div (for example 50% each for 2 child divs, 25% for 4 child divs etc) since these vary according to number of divs and cannot be calculated accurately sometimes
Well, I went the jQuery route...
http://jsfiddle.net/dtgEt/1/
I would like to point out that while yes, some people will just use a table, a table is for displaying tabular data, not layout. A div has no semantic meaning and therefor is a better choice, in my opinion (unless it is actually tabular data that your are publishing to the web).
My solution works in IE 7 and probably would in IE 6. If you want to align your content in the center of the container there are many good ways to do that others have suggested (beat me to it).
If you need the formatting of a table, but you have to support older browsers that don't have support for display:table, then use a table. It's pretty much that simple.
Sometimes a table is the appropriate option, and sometimes it's the only option that will work without adding some moderately-risky JS or jQuery to simulate the formatting of a table.
For instance, a table (or display:table, which amounts to the same thing) is the only natural way to have true vertical centering of dynamic content. It's also the only natural way to enforce equal-height columns for dynamic content. And in general, a table is appropriate anytime you need to display a data grid of some sort.

What is vertical-align used for in CSS?

I am new to the world of coding as well as CSS and recently came across the property vertical-align. Having read a number of articles on what it is, I am still clueless on what it is for and when do you use it?
My understanding is that it is used for inline elements such as text, images, etc as well as text or other inline elements in a table. They cannot be used for block element such as div, h1, etc.
If my understanding is right, apart from aligning text vertically to say an image or using subscript or superscript, what other purpose does it serve?
It's used the vertical align inline elements indeed. Block level elements will ignore this property. So your understanding is right.
This blog gives some background information on vertical-align with some examples. It's mainly used to vertically position an image in a line of text. Or to replace the valign attribute on tablecells.
So it seems you are understanding it quite right. See w3schools for the details on the vertical-align property.
Just to be clear; do not try to use vertical-align to position a blocklevel element like a div. It will not work, as you already mentioned, it's for inline elements like images in a line of text. Using display: table-cell; and vertical-align on an element is a hack, please use other CSS techniques to vertically align stuff in an div whenever possible.
It's always worth reading the specs if you want to learn about a specific property:
http://www.w3.org/TR/CSS21/visudet.html#propdef-vertical-align
A common use case is vertical centering (in combination with display: table-cell):
http://jsfiddle.net/7eTb2/
div {
background: #ccc;
width: 200px;
height: 300px;
padding: 5px;
display: table-cell;
vertical-align: middle
}
It's somewhat difficult to vertically center without using this technique.
Another common use case is when it comes to elements that are inline or inline-block.
See here for examples of what happens with different vertical-align values:
http://www.brunildo.org/test/inline-block.html
Another good link to read: http://css-tricks.com/what-is-vertical-align/
However, it's real use is getting me upvotes, see:
https://stackoverflow.com/search?tab=votes&q=user%3a405015%20%22vertical-align%3a%20top%22
:)
Others have been mostly correct about vertical-align. The reality is that it works, just not how you think. It's for inline elements, not block elements.
In this case, a fiddle is worth a thousand words. :)
http://jsfiddle.net/JJfuj/
vertical align, by the W3C and by how most(tm) interpret it, is only used/takes affect in elements that are table-cells (<td>), and on some browsers, elements with the display: table-cell declaration.
The rest of the time, it is largely disregarded by browsers.
Vertical align is for just what it sounds like. It aligns the element vertically within the parent object; however, not all browsers interpret it the same.
Here's a little more in-depth information on the parameter values available.

Divs side by side without floats or position:absolute

I'm trying to find a way to place divs side by side without using floats or position:absolute. The divs will have a set width, and may have floated elements inside of them. This is for a CMS where the user will be able to drag content elements to organize them. They do not have to be divs, I just don't know of any other type of HTML tag that would work better.
Basically the end result is for a CMS in which the user can organize content elements by dragging them. Unfortunately with floats, if you want to do anything that involves putting divs underneath each other, everything will go down to below the tallest div above it, even if it could fit underneath something else. i.e. 3 elements, 2 of which should be stacked on the left with a third one on the right that has a height somewhere in between the two.
Inline-block is out as it isn't supported by IE (although I'd love to be a dick and just have chrome frame required...) and doesn't work for this purpose anyway.
I'm a little confused that you mention dragging elements, but your title states you do not want to use position:absolute as a solution... most scripts I am aware of use that for the dragging process, so why would you not use it for the positioning of it to place them side-by-side?
Do you have fixed number of columns ie elements horizontally arranged side by side ? If yes one thing i can think of is having those many floated unordered lists and each element will be an li
When an element is dragged and dropped inside the same ul, its index in the ul is changed. When its dragged across uls,its removed from this list and appended to the other and arranged as in case 1. Just have an idea right now... will have to try it
The only option I can think of that doesn't use the techniques you've mentioned (position:absolute, display: inline-block, and float) is to use a table.
<table>
<tr>
<td><div id="div1">...content...</div></td>
<td><div id="div2">...content...</div></td>
</tr>
</table>
It's possible that you could use:
<div id="container">
<div id="div1">...content...</div>
<div id="div2">...content...</div>
</div>
with css:
#container {display: table; } /* you might need another child div with 'display: table-row' but I can't remember off-hand */
#div1 {display: table-cell; width: 50%; /* other css */}
#div2 {display: table-cell; /* width: 50%; other css */}
This is the best I can think of, and I dislike using tables for non-tabular purposes. But to each their own. =/
Are you just looking for a way to drag/drop and organize content? Have you seen JQuery UI's "Sortable"?
http://jqueryui.com/demos/sortable/