CSS: two columns

2020-02-07 04:05发布

I can't figure out how to achieve the following layout with CSS (probably because I don't actually know CSS).

I have a bunch of divs like this:

<div class="right"> <p>1</p> </div>
<div class="left">  <p>2</p> </div>
<div class="left">  <p>3</p> </div>
<div class="left">  <p>4</p> </div>
<div class="right"> <p>5</p> </div>
<div class="right"> <p>6</p> </div>

(not the real contents)

Now I want the layout to look like two equal columns of divs, with the "right" ones on the right, and the "left" ones on the left, thus:

2 1
3 5
4 6

[Edit: In a previous version of this question I had textareas inside the divs, and the divs all had different names like "one" and "xyz".] I tried something like

div.right { width:50%; float:right; clear:right; }
div.left { width:50%; float:left; clear:left;}

but it doesn't quite work: It produces something like:

2 1
3 
4 5
  6

(without the "clear"s, it blithely produces

2 1
3 4
6 5

which is not what is wanted).

It is apparent that it can be made to work if the divs are ordered differently, but I'd like not to do that (because these divs are generated dynamically if the browser has Javascript, and I don't want to change the actual order that is displayed in the absence of Javascript, for semantic reasons). Is it still possible to achieve the layout I want?

[For what it's worth, I'm willing to have it not work on IE or older versions of other browsers, so if there is a solution that works only on standards-compliant browsers, that's okay :-)]

标签: css layout
11条回答
ら.Afraid
2楼-- · 2020-02-07 04:40

Check out the 960 Grid System. I have used this on projects in the past and I have to say it works pretty well. Not only that, it is easy to use and is consistent across browsers :D

Using this framework:

<html>
    <head>
        <link rel="stylesheet" type="text/css" media="all" href="css/reset.css" />
        <link rel="stylesheet" type="text/css" media="all" href="css/text.css" />
        <link rel="stylesheet" type="text/css" media="all" href="css/960.css" />
     </head>
     <body>
     <div class="container_16">
         <div class="grid_1 alpha" style="text-align:center;">
            2
         </div>
         <div class="grid_1 omega" style="text-align:center;">
            1
         </div>
         <div class="clear"></div>
         <div class="grid_1 alpha" style="text-align:center;">
            4
         </div>
         <div class="grid_1 omega" style="text-align:center;">
            3
         </div>
         <div class="clear"></div>
         <div class="grid_1 alpha" style="text-align:center;">
            5
         </div>
         <div class="grid_1 omega" style="text-align:center;">
            4
         </div>
    </div>
</body>
</html>

alt text http://img40.imageshack.us/img40/6889/cd3cc920a04b80e06b8efef.png

The bar on top of the text is from my browser, not part of the CSS or layout.

查看更多
小情绪 Triste *
3楼-- · 2020-02-07 04:43

You have Javascript - why not use it?

You said this:

These divs are generated dynamically if the browser has Javascript, and I don't want to change the actual order that is displayed in the absence of Javascript, for semantic reasons...

You're only displaying these <div>s if the user has Javascript - why not use Javascript to rearrange them? If you move #4 to be after #5, it looks fine with your current CSS.

So (with jQuery):

$("div:eq(3)").remove().insertAfter("div:eq(4)");
查看更多
Anthone
4楼-- · 2020-02-07 04:44

I felt guilty that the pure css method didn't work, but if you don't mind using JavaScript to get what you're after, then here's some jQuery that'll work (someone else will probably be able to clean this up for you if you don't like the bloat).

<style>
  #container { width: 500px; border: 1px grey solid; overflow: hidden; }
  #container .rightSide { width: 250px; float: right; }
  #container .left { width: 250px; background: red; padding: 20px 0; overflow: hidden; text-align: center; }
  #container .right { width: 250px; background: green; padding: 20px 0; overflow: hidden; text-align: center; }
</style>
<script type="text/javascript">
$(document).ready(function() {
  $('#container').prepend('<div class="rightSide"></div>');
  $('#container div.right').each(function() {
    var $rightContent = $(this).remove().html();
    $('.rightSide').append('<div class="right">' + $rightContent + '</div>');
  });
});
</script>
<div id="container" >
  <div class="right"> <p>1</p> </div>
  <div class="left">  <p>2</p> </div>
  <div class="left">  <p>3</p> </div>
  <div class="left">  <p>4</p> </div>
  <div class="right"> <p>5</p> </div>
  <div class="right"> <p>6</p> </div>
</div>
查看更多
在下西门庆
5楼-- · 2020-02-07 04:47

I'll leave the rest of this answer in place so that someone else can see what my initial thoughts were, but this approach actually fails and requires that there are always more floating elements than none floating.

I think this is your solution (not tested).

.left { width: 51%; float: left; }
.right { width: 49%; }

The 51% stops them from floating next to each other and then just let all the .right content wrap up around those floated blocks.

Thinking less often gives you more with HTML/css, and again - NO to using tables for layout.

===[edit]===

I ran a test on this and it does work with a couple of tweaks AND if you know the first item is floating left (or right to reverse the behavior).

<style>
  div div { text-align: center; padding: 20px 0; overflow: hidden; }
  .left { width: 251px; float: left; background: red; }
  .right { width: 249px; background: green; }
</style>
<div style="width: 500px;" >
  <div class="left"> <p>1</p> </div>
  <div class="right">  <p>2</p> </div>
  <div class="left">  <p>3</p> </div>
  <div class="left">  <p>4</p> </div>
  <div class="right"> <p>5</p> </div>
  <div class="right"> <p>6</p> </div>
</div>
查看更多
We Are One
6楼-- · 2020-02-07 04:47

Tables are a perfectly acceptable solution for this IMHO.

The backlash against tables was directed towards using them for the entire site layout. But if you need to display your data in rows and columns...... that's what tables were made for :)

If you still are interested in a viable cross browser CSS solution I would look at using a framework. It will save you hours of time in trying to get your page to look right.

http://www.blueprintcss.org/ is an excellent framework IMHO.

查看更多
贼婆χ
7楼-- · 2020-02-07 04:52

Solution 1

If you can afford to duplicate HTML:

.left-column .right, .right-column .left {
    display: none;
}

Solution 2

Wait a little until browsers support CSS3:

.right {
    position: flow(side); 
}

Solution 3

If your divs have the same height, use the indirect adjacent sibling combinator. Even though it belongs to CSS Level 3, it's already well-supported:

.container {
    position: relative;
}

.left, .right {
    position: absolute;
    top : 0;
    width: 50%;
} 

.left {
    left: 0;
}

.right {
    left: 50%;
}

.left ~ .left, .right ~ .right {
    top : 100px;
}

.left ~ .left ~ .left, .right ~ .right ~ .right {
    top : 200px;
}

.left ~ .left ~ .left ~ .left, .right ~ .right ~ .right ~ .right {
    top : 300px;
}

... /* you need to include as many rules as the maximum possible height */
查看更多
登录 后发表回答