CSS: layout DL as flexible table with paddings - css

I want to use DL/DT/DD approach to organize my forms. I need to structure them as tables (a column for label and a column for value). The following html+css works fine but till I add margin or padding to dt and/or dd.
<html><head>
<style>
dl {
width: 100%;
overflow:hidden;
}
dt {
float: left;
width: 50%;
margin: 0px;
padding: 0px;
}
dd {
float: left;
width: 50%;
margin: 0px;
padding: 0px;
}
</style></head>
<body>
<dl>
<dt>first name</dt>
<dd><input />
</dl>
</body></html>
If I replace "margin: 0px" in dt's style with "margin: 5px" or the same for padding then dd element jumps on next row.
I need:
2-column table layout for DL
do not use absolute widths (that's because I'm using "50%" as columns' widths)
add some margin/padding to dt/dd
How to add margin/padding and keep relative widths (50%/50%)?
p.s. I've seen many similar questions about DL and table layout, but my question about combination of dl + table layout + relative widths + paddings. I can get it working with relative widths or paddings but not both.

All you need is to specify the magical property: box-sizing: border-box. You can then use padding all you want without increasing the width.
JSFiddle Demo
See also: box-sizing support in ie7
box-sizing addresses padding and borders, but not margins. If you want to use margin as well, use calc() to subtract the margin from the width. For example, if you want a 5px left margin:
dd {
margin: 0 0 0 5px;
width: calc(50% - 5px);
}
But, calc() does not work in IE8 or earlier.
more on calc()

I found a solution now (under the shower!)
Give the outer DL display:block and some padding to the left and right that add up to the margins and padding the DT and DD. Now the 100% of the DL are the basis for the 50% of the inner elements. Now give these your desired margins and paddings. Until now it won't work as desired. Yet there's things still to come. Add up all the margins and paddings of the DT and the DDrespectively. And give each a negative margin (the DT to the left and the DD to the right) so all the margins and paddings of them add up to zero/naught/niente/nada. E VoilĂ ! Now you can have any combination of percentage you want, e.g. 30% - 70%.
dl {
display: block;
overflow:hidden;
padding: 5px 15px 5px 20px;
}
/* the -15px in the margin is to compensate for the 5px in the margin and the 2 x 5px in the padding */
dt {
float: left;
width: 30%;
margin: 0px 5px 0 -15px;
padding: 5px;
background: yellow;
}
/* the -10px in the margin is to compensate for the 2 x 5px in the padding */
dd {
float: left;
width: 70%;
margin: 0px -10px 0 0px;
padding: 5px;
background: yellow;
}
http://jsfiddle.net/HerrSerker/AADG7/

You just need to make sure that each dt clears the previous alignment;
add
dt {
clear:both;
}
to the css defined above
see http://jsfiddle.net/Nd2sH/

I would use nested DIVs or spans, inside the and elements. Right now, the 50% width is conflicting with the need for a padding or a margin.
Something like this would accomplish the same thing.
<dt><div style="margin:5px;">first name</div></dt>
<dd><div style="margin:5px;"><input /></div></dd>

The only things about it you can do:
Use JavaScript to get the width of the DL and then calculate the width of the DT and the DD so that the width of these plus the margin and the padding add up to the 100% of the DL
Or set a fixed width for the first column and no width for the second
Or wrap the content of each DT and DD with a DIV and give this the margin and padding

Related

CSS use padding for all except images

I'm using flexbox to build my page and I'm using the following to apply the same rules to all elements inside an article:
#article-wrapper > *
{
flex:1 100%;
padding:0px 20px 0px 20px;
box-sizing: border-box;
}
I then use media queries to change the layout but that's not the point of my problem.
Inside #article-wrapper, I have a couple of DIV elements containing text and images. With the CSS code above, everything gets a left & right padding of 20 px. It's fine but I'd like image to have a padding of 0 px.
Negative padding is not possible and applying the padding locally on each element would force me to wrap all text in or
I thought of doing this:
#article-wrapper > *
{
flex:1 100%;
box-sizing: border-box;
}
#article-wrapper:not(img) > *
{
padding:0px 20px 0px 20px;
}
But with this, images remain unaffected.
Do you see any way of creating an exception for one type of element ? (images in this case)
Here is an example: https://wp.laurentwillen.be/circuits/circuit-ecosse/chateau-culzean-et-drumlanring-dumfries-galloway
Thanks
Like so
#article-wrapper > *:not(img) {
padding:0px 20px 0px 20px;
}

Navbar links should be all tall like the taller one

I have a navigation bar with 4 links floated.
While width of each one is 25% of total width of NAV, height is not fixed because text of a link could be longer than others and span across 2 rows, like in this example.
#first-level-navigation .mega-link {
background: linear-gradient(180deg, #ffffff 0%, #ffffff 60%, #eaeeee 100%) repeat scroll 0 0 rgba(0, 0, 0, 0);
border: 1px solid #cccccc;
padding: 0;
text-transform: uppercase;
width: 25%;
}
#first-level-navigation .mega-link a {
color: #00643c;
display: inline-block;
padding: 10px;
text-align: center;
text-decoration: none;
width: 100%;
}
I would like that height of smaller links will extend to height of taller one in case like mine, in which last link span on 2 rows if window is smaller enough. How to obtain it, withous forcing height in px? I tried with height:100% but it was unuseful
You can use display:table/table-cell:
#first-level-navigation{
display:table;
}
.mega-link{
display:table-cell;
vertical-align:middle;
}
JSFiddle
Aslo, you have to add browser prefixes for box-sizing: border-box - here's a good article about it by Paul Irish.
With jQuery(in Coffeescript):
if $('html').length > 0
link = $('.mega-link')
# Determine heights
link_height = link.height()
# Applys heights
link.css "height", link_height
# when window resizes, calculate and apply again
$(window).on 'resize', ->
# re-determine height
link_height = link.height()
# Apply heights
link.css "height", link_height
After few years, new modern CSS techniques could be used to solve this issue, using Flexbox Layout.
Starting from #Vucko's jsFiddle (proposed in its answer), I slightly modified it to use Flexbox in the following way:
#first-level-navigation{
display:flex;
}
.mega-link{
flex:1;
}
This code solve "equal heights" issue but to mantain also centered vertical alignment, is necessary to make flex also each .mega-link, so the complete code becomes the following:
#first-level-navigation{
display:flex;
}
.mega-link{
flex:1;
display:flex;
align-items:center;
}
Please, note also that Flexbox allows to avoid specific declaration of fixed width (so width:25%; can be removed, replaced in its function by flex:1;), so becomes easier change number of .mega-link elements with auto adaptation of each one.

How to Fix Collapsing Top and Bottom Margins?

I'm new to CSS and I'm trying to understand how to fix the following line from not working for top and bottom margins. It works for side margins just fine, however:
.contents {
...
margin: 10px 10px 10px 10px;
}
Example: http://jsfiddle.net/LCTeU/
How do I fix this?
Edit:
I've also tried padding the container instead, and that just expands the container to maximum size (why?):
.container {
...
padding: 10px 10px 10px 10px;
}
Use overflow:auto on any of the elements that are involved with the collapse. For example:
article {
overflow:auto;
}
jsFiddle example
This answer is based off of the fiddle you provided.
I think your approach is incorrect in that your applying a margin to the article to space it within the parent div tag. It is better to use padding in this case, since your attempting to separate the content from its outside border. So apply:
article {
//display: block;
clear: both;
padding: 10px;
}
This will cause the article tags to increase in size, however the borders of the container div elements will now be touching. To create space between elements a margin is applied.
.rounded-box {
background-color: #959392;
border-radius: 15px;
margin: 10px 0px;
}
Working Example http://jsfiddle.net/LCTeU/4/
So just to recap, when you want to create space between two elements use margin. When you want to create space between an element and its border (or you want an element to be surrounded by whitespace) use padding.
I found a fix that does not require a padding, and does not require changing the overflow of the container element:
article:after {
content: "";
display: block;
overflow: auto;
}
The idea being that we add another element at the bottom that disrupts the collapsing margin, without affecting the height or padding.
As per the fix that Erik Rothoff suggested, which does not seem to work in Safari, first I tried the following:
article:after {
content: "";
display: inline-block;
overflow: auto;
}
This does work in Safari but takes up space which I could not get rid off, messing up the grid so much that I would need to change margins.
Then I decided to combine the two by doing the following:
article:after {
content: "";
display: block;
padding-top: 1px;
margin-top: -1px;
}
This works in Safari, has an acceptable height of 1px which is negated by the negative margin top.

How can I prevent fixed width elements from being pushed around?

I currently have a footer that uses a 3 column layout with a fixed center and fluid sides in order to get a nice box shadow effect. When the window is too small however, it pushes the footer to the left, and messes everything up.
I can't seem to figure out how to make sure the footer divs do not get pushed around. I keep running into this problem with my layouts.
The layout I am working on is here, and a screencast showing the problem is here.
The easiest solution is simply to add min-width:980px to #container.
#container {
background: none repeat scroll 0 0 #A8D9A7;
height: 100%;
min-height: 100%;
position: relative;
z-index: 5;
min-width: 980px; /* add this */
}
The 980px figure comes from the width:960px + padding-left:10px + padding-right:10px of the #content-container.
The container element for your main page body (<div id="body">) has computed padding-left of 10px, and the second container element, (<div id="content-container">) adds another padding-left of 10px, meaning your main body is padded from the left by 20px.
Whereas the container for your footer (<div id="footer-container">) has computed padding-left of 0.
If you add this, it will fix your problem. #footer-container {padding: 0 20px;}
Revised as the above solution messed up bottom box-shadow.
In the #footer-left-outer { rule change:
margin-right:470px;
to:
margin-right:-490px;
In the #footer-right-outer { rule change:
margin-left:-470px;
to:
margin-left:-490px;
In the #footer { rule change:
padding: 10px 10px 10px 10px;
width: 940px;
to:
padding: 10px 30px;
width: 980px;
I now understand why you were using the outer-right and outer-left.
I found a different solution that includes the partial box-shadow effect:
http://jsfiddle.net/nottrobin/Cr4NF/10/
It avoids the need for footer-left-outer and footer-right-outer but I'll leave it up to you to decide if it's neater.
It makes use of :before which only works in IE8 onwards:
http://caniuse.com/#search=:before
But then box-shadow doesn't work in IEs < 9 anyway:
http://caniuse.com/#search=box-shadow

css dilemma(large backgrounds)

I'm using a large background in <body> tag and I want to make a container div with a width of 960px.
I want the container div to be positioned 15px down from the top, I guess i have to use position:absolute.
My dilemma is; the rest of the div's inside the container have to contain the same position or i could continue this like an normal 960px wide website?
Sorry for my bad english.
Please help me!
This should give your container a 960px width and center it with a 10px top (and bottom!) margin.
#container {
width: 960 px; /* set width for container */
margin: 10px auto; /* 10px top and bottom, center screen */
}
You don't have to use absolute positioning. A simple
body {margin: 0; padding: 0}
#container {width: 960px; margin: 15px 0 0;} /* or margin: 15px auto 0 */ if you want it centered
will do :)
You do not need to use position:absolute; what that does is puts a div in a specific place on the page irrleevant of broswer window size which isn't what you want in this instance,
What you need is simply a margin-top:$$px;
If you are using an id use the # identifier:
#container {
margin-top:15px;
width:960px;
}
If you are using a class use the . identifier:
.container {
margin-top:15px;
width:960px;
{
All divs within this tag can be written and position as they normally would, no extra padding or margins necessary.

Resources