visually swap divs with css

JavaScript and client side scripting.

Moderator: General Moderators

User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Post by Weirdan »

The original poster also seemed to want to do this in a more dynamic way, as in, being able to swap the two divs after they have been originally rendered on the screen.
No, that wasn't my intention.
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Post by Weirdan »

The only way to do it in pure CSS is to use absolute positioning.
Even with absolute position, how would you calculate the top for the first div if the height of the second div is unknown?
User avatar
Benjamin
Site Administrator
Posts: 6935
Joined: Sun May 19, 2002 10:24 pm

Post by Benjamin »

Weirdan wrote:Where is the dynamic you're referring to here?
I thought you were wanting an end user to be able to move a box up or down in the document flow.

If you want the bottom div(2) to show on top, just float it left and set the width to the same width as the container. div1 one will drop below it.
matthijs
DevNet Master
Posts: 3360
Joined: Thu Oct 06, 2005 3:57 pm

Post by matthijs »

If you want the bottom div(2) to show on top, just float it left and set the width to the same width as the container. div1 one will drop below it.
But how do you get the first one below? In the html the first div is being parsed first. It gets a default width of 100%. Ok, first box is set. Now in the code comes the second div. Float it left and give it 300px width (same as container div). It will neatly float left. .. below the second div.

I don't see it. Please enlighten me :)
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Post by Weirdan »

I thought you were wanting an end user to be able to move a box up or down in the document flow.
No, they have enough dynamic without moving these boxes around the document tree :lol:

Perhaps explaining my situation could help posters to understand what was I after:
I have pretty standard three-column layout where left and right columns are of fixed width and floated to right and left respectively. Because they are floated when viewed on desktop computers, they have to appear in document source before the middle column. But when viewed on handheld there isn't enough space to have three columns. I would like to degrade the layout to single column in this case. Naturally, most important content is placed in the middle column, thus in single-column variant I want it to appear before the content that was in side bars. I thought I would be able to keep the markup the same and achieve the required layout using different css only.
User avatar
Benjamin
Site Administrator
Posts: 6935
Joined: Sun May 19, 2002 10:24 pm

Post by Benjamin »

Floats are taken out of the document flow, order does not matter, it will float to the top of the container.
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Post by Weirdan »

Floats are taken out of the document flow, order does not matter, it will float to the top of the container.
Have you tested it? I have, and I can tell you from my experience that order does matter.
User avatar
Oren
DevNet Resident
Posts: 1640
Joined: Fri Apr 07, 2006 5:13 am
Location: Israel

Post by Oren »

astions is right I believe. I used floats to do exactly what you need few weeks ago, the only problem was IE - as always :P
User avatar
Benjamin
Site Administrator
Posts: 6935
Joined: Sun May 19, 2002 10:24 pm

Post by Benjamin »

Well I screwed around with it for a while and couldn't get it to work. I'm sure there is a way to do it though.

This is the closest thing that I found so far..

http://www.fu2k.org/alex/css/onetruelay ... nteractive

EDIT: I wrote this up and it works in firefox. It uses javascript though..

Code: Select all

<html>
<head>
<meta/>
<title>Test</title>
<style type="text/css">
#container {
  width: 768px;
  height: 500px;
  border-width: 1px;
  border-style: solid;
  border-color: #000000;
}

#div1 {
  background-color: #084275;
  border-width: 1px;
  border-style: solid;
  border-color: #000000;
}

#div2 {
  background-color: #254708;
  border-width: 1px;
  border-style: solid;
  border-color: #000000;
}

</style>
<script language="JavaScript">
<!--
function swap() {
    var box1 = document.getElementById('div1').innerHTML;
    var box2 = document.getElementById('div2').innerHTML;
    document.getElementById('div1').innerHTML = box2;
    document.getElementById('div2').innerHTML = box1;
}
-->
</script>
</head>
<body onload="swap();">
<div id="container">
  <div id="div1">
    <p>This is div 1 This is div 1 This is div 1 This is div 1 This is div 1 This is div 1 This is div 1 This is div 1 This is div 1 This is div 1 This is div 1</p>
  </div>
  <div id="div2">
    <p>This is div 2 This is div 2 This is div 2 This is div 2 This is div 2 This is div 2 This is div 2 This is div 2 This is div 2 This is div 2 This is div 2 This is div 2 This is div 2</p>
  </div>
</div>
</body>
</html>
bg
Forum Contributor
Posts: 157
Joined: Fri Sep 12, 2003 11:01 am

Post by bg »

astions wrote:Well I screwed around with it for a while and couldn't get it to work. I'm sure there is a way to do it though.

This is the closest thing that I found so far..

http://www.fu2k.org/alex/css/onetruelay ... nteractive

EDIT: I wrote this up and it works in firefox. It uses javascript though..

Code: Select all

<html>
<head>
<meta/>
<title>Test</title>
<style type="text/css">
#container {
  width: 768px;
  height: 500px;
  border-width: 1px;
  border-style: solid;
  border-color: #000000;
}

#div1 {
  background-color: #084275;
  border-width: 1px;
  border-style: solid;
  border-color: #000000;
}

#div2 {
  background-color: #254708;
  border-width: 1px;
  border-style: solid;
  border-color: #000000;
}

</style>
<script language="JavaScript">
<!--
function swap() {
    var box1 = document.getElementById('div1').innerHTML;
    var box2 = document.getElementById('div2').innerHTML;
    document.getElementById('div1').innerHTML = box2;
    document.getElementById('div2').innerHTML = box1;
}
-->
</script>
</head>
<body onload="swap();">
<div id="container">
  <div id="div1">
    <p>This is div 1 This is div 1 This is div 1 This is div 1 This is div 1 This is div 1 This is div 1 This is div 1 This is div 1 This is div 1 This is div 1</p>
  </div>
  <div id="div2">
    <p>This is div 2 This is div 2 This is div 2 This is div 2 This is div 2 This is div 2 This is div 2 This is div 2 This is div 2 This is div 2 This is div 2 This is div 2 This is div 2</p>
  </div>
</div>
</body>
</html>
InnerHTML is not part of the javascript spec. It was introduced by IE and other browsers implemented it because of its wide usage. Il lpost something soon
User avatar
Benjamin
Site Administrator
Posts: 6935
Joined: Sun May 19, 2002 10:24 pm

Post by Benjamin »

Well the fact that it works is great considering I don't know javascript and guessed it.
bg
Forum Contributor
Posts: 157
Joined: Fri Sep 12, 2003 11:01 am

Post by bg »

astions wrote:Well the fact that it works is great considering I don't know javascript and guessed it.
for sure :D

Problem is that you're not actually swapping divs, just the contents contained within each div. Swapping divs would cause the background color to swap as well. I guess im confused as to what you're trying to do
bg
Forum Contributor
Posts: 157
Joined: Fri Sep 12, 2003 11:01 am

Post by bg »

Here is the fully w3c compliant solution. Note the div themselves are acually swapped, not just their contents

Code: Select all

<html>
<head>
<meta/>
<title>Test</title>
<style type="text/css">
#container {
  width: 768px;
  height: 500px;
  border-width: 1px;
  border-style: solid;
  border-color: #000000;
}

#div1 {
  background-color: #084275;
  border-width: 1px;
  border-style: solid;
  border-color: #000000;
}

#div2 {
  background-color: #254708;
  border-width: 1px;
  border-style: solid;
  border-color: #000000;
}

</style>
<script language="JavaScript">
<!--
function swap() {
    var container = document.getElementById('container');
    var box1 = document.getElementById('div1');
    var box2 = document.getElementById('div2');
    container.insertBefore(box2,box1);
}
-->
</script>
</head>
<body onload="swap()">
<div id="container">
  <div id="div1">
    <p>This is div 1 This is div 1 This is div 1 This is div 1 This is div 1 This is div 1 This is div 1 This is div 1 This is div 1 This is div 1 This is div 1</p>
  </div>
  <div id="div2">
    <p>This is div 2 This is div 2 This is div 2 This is div 2 This is div 2 This is div 2 This is div 2 This is div 2 This is div 2 This is div 2 This is div 2 This is div 2 This is div 2</p>
  </div>
</div>
</body>
</html> 
It is good practice to avoid innerHTML. It is tempting to use as someone new to javascript since it is an easy way out, but it is not part of the w3c standard and the only reason it sticks around is to support legacy websites.
matthijs
DevNet Master
Posts: 3360
Joined: Thu Oct 06, 2005 3:57 pm

Post by matthijs »

I have pretty standard three-column layout where left and right columns are of fixed width and floated to right and left respectively. Because they are floated when viewed on desktop computers, they have to appear in document source before the middle column. But when viewed on handheld there isn't enough space to have three columns. I would like to degrade the layout to single column in this case. Naturally, most important content is placed in the middle column, thus in single-column variant I want it to appear before the content that was in side bars. I thought I would be able to keep the markup the same and achieve the required layout using different css only.
Well, in that case there are solutions to your problem. No need to swap divs or use javascript. Use the content order you want and use one of the nifty negative margin techniques to layout the cols in the right way. Maybe something like Ryan Brill did in his alistapart article or Thierry or the one true layout astions linked to.

You could even use absolute positioning, if that doesn't compromise other layout aspects. Like giving the maincontent div a left and right margin and use absolute positioning for left and right cols. Only problem you might have then is the footer positioning - if you have one and want it to stretch the full width - and possible overlap when content of one of the cols getting longer. But I know there are solutions for that too.
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Post by Weirdan »

margin techniques to layout the cols in the right way
Correct me if I'm wrong, but would it be possible to reorder blocks using negative margins from:

Code: Select all

+--------------++---------------------++--------------+
|              ||                     ||              |
| left column  ||    center column    || right column |
|              ||                     ||              |
|              ||                     ||              |
+--------------++---------------------++--------------+
to

Code: Select all

+-----------------+
|                 |
|   center column |
|                 |
+-----------------+
+-----------------+
|                 |
|  left column    |
|                 |
+-----------------+
+-----------------+
|                 |
|  right column   |
|                 |
+-----------------+
?
Post Reply