How to Make each grid-column Individually Selectable?

Hello & Thanks :

I am doing that here with fake Tables to demonstrate what I mean :
http://vmars.us/reads/vmTemplate-2Parallel-Tables-P-Editable.html
(It is contenteditable so you can edit it see what I mean)
But the problem comes in when I enter text that overflows ,
the tables get stacked on top of each other .

So I am hoping I can do it with grid , but so far not so good .
Here is my grid code attempt .
Also the rows need to line up .

<!DOCTYPE html>
<html>
<head>
<style>
.grid-container {
  display: grid;
  grid-template-columns: 100px 100px ;
  grid-gap: 10px;
  background-color: #2196F3;
  padding: 10px;
}

.grid-container > div {
  background-color: rgba(255, 255, 255, 0.8);
  text-align: center;
  padding: 20px 0;
  font-size: 30px;
}

.item1 {
  grid-column-start: 1;
  grid-column-end: 1;
//  grid-area: 1;
}
.item2{
  grid-column-start: 2;
  grid-column-end: 2
}

</style>
</head>
<body>

<h5>Make-each--grid-column--Individually-Selectable.html</h5>

<p>How make separate grid-area for col1 and col2</p>

<div class="grid-container">
  <div class="item1">1</div>
  <div class="item1">2</div>
  <div class="item1">3</div>  
  <div class="item2">4</div>
  <div class="item2">5</div>
  <div class="item2">6</div>
</div>

</body>
</html>

Thanks

1 Like

You would have needed to set a max-width on each column so that two will always fit across. Inline-block elements will shrink to fit content and expand as wide as they are allowed unless you constrain the width in somw way.

It is unclear what problem you are trying to solve and what the criteria are that the code needs to work with. You will need to define the problem in unambiguous terms and then explain what you would like to happen.

Therefore the code below is probably not what yo were looking for but may serve as a start :slight_smile:

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Untitled Document</title>
<style>
.grid-container {
	display: grid;
	grid-template-columns:minmax(100px, 500px) minmax(100px, 500px) ;
	grid-template-areas:"grid1 grid2"  "grid3 grid4"  "grid5 grid6";
	grid-gap: 10px;
	background-color: #2196F3;
	padding: 10px;
	justify-content:center;
}
.grid-container > div {
	background-color: rgba(255, 255, 255, 0.8);
	text-align: center;
	padding: 20px 0;
	font-size: 30px;
}
.item1 {grid-area: grid1;}
.item2 {grid-area: grid3;}
.item3 {grid-area: grid5;}
.item4 {grid-area: grid2;}
.item5 {grid-area: grid4;}
.item6 {grid-area: grid6;}
</style>
</head>

<body>

<h1>Make-each--grid-column--Individually-Selectable.html</h1>
<p>How make separate grid-area for col1 and col2</p>
<div class="grid-container">
  <div contenteditable="true" class="item1">1</div>
  <div contenteditable="true" class="item2">2</div>
  <div contenteditable="true" class="item3">3</div>
  <div contenteditable="true" class="item4">4</div>
  <div contenteditable="true" class="item5">5</div>
  <div contenteditable="true" class="item6">6</div>
</div>

</body>
</html>

BTW the link to your site pops up a dangerous page warning from Bitdefender on my mac!

Thanks :

  1. I want to create a table or grid like structure with two columns and many rows .
  2. Where each column is selectable (so I can select column then copy and paste) .
  3. Where the width of each is 50% .
  4. Where when the window is resized horizontally the right-most column stays where it is and does not move to the bottom of a stack (ie. ) .

Where in your example I could select column 1 (1,2,3) ,
or select column 2 (4,5,6) .
I hope this is more clear .
Thanks

Yes that’s basically what the code I gave you does.

CSS does not allow selection of data you would need JS to do that if I understand correctly. You can copy and paste content by the usual highlight method and dragging the cursor over the text you want to copy but once you set contenteditable="true" to true then you can only copy the text in that element and not all other elements in that column.

As son as you set contenteditable then you can only highlight the text in that element (browsers may vary but Chrome only allows the current element to be selected).

You could create a nested grid and put contenteditable on the column but then that would stop you having separate row styling as editing it would duplicate the whole element including html and not just the content.

e.g.

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Untitled Document</title>
<style>
.grid-container {
	display: grid;
	grid-template-columns:minmax(100px, 50%) minmax(100px, 50%);
	grid-template-areas:"grid1 grid2";
	grid-gap: 10px;
	background-color: #2196F3;
	padding: 10px;
	justify-content:center;
}
.grid-container > div {
	text-align: center;
	font-size: 30px;
}
.item1, .item2 {
	grid-area: grid1;
	display:grid;
	grid-template-rows: 1fr;
}
.item2 {
	grid-area: grid2;
}
.inner {
	background-color: rgba(255, 255, 255, 0.8);
	padding: 20px 0;
}
.inner:last-child {
	margin-bottom:0;
}
</style>
</head>

<body>
<h1>Make-each--grid-column--Individually-Selectable.html</h1>
<p>How make separate grid-area for col1 and col2</p>
<div class="grid-container">
  <div  contenteditable="true" class="item1">
    <div  class="inner">Col 1 row 1<br>
      test</div>
    <div  class="inner">Col 1 row 2</div>
    <div class="inner">Col 1 row 3</div>
  </div>
  <div class="item2" contenteditable="true">
    <div class="inner">Col 2 row 1</div>
    <div class="inner">Col 2 row 2</div>
    <div class="inner">Col 2 row 3</div>
  </div>
</div>
</body>
</html>

You set it to 100px in your grid example? Just set it to 50% instead. In my last example I used a minmax rule here…

grid-template-columns:minmax(100px, 50%) minmax(100px, 50%);

The columns won’t drop below in both the examples I have given.:slight_smile:

It sounds to me as though you will need to add some JS connected to a button that will allow the user to highlight and copy the whole column rather than them trying to drag the mouse across multiple rows.

All assuming I have understood correctly :slight_smile:

1 Like

Thanks
I found an example here ,
but only cells 5,6,7 are selectable downward .
That’s the behavior I am after .
https://www.w3schools.com/cssref/tryit.asp?filename=trycss_grid-area
Thanks

That example doesn’t use the contenteditable attribute that you were using to edit the text. As I said above there is n o issue in selecting the text without that attribute.

Here is my example code without that attribute and you can copy each column as required,

As soon as you add the attribute mentioned then you can only copy the one cell. Unless you use the example from my previous post but with the caveats already mentioned.

Of course I may be misunderstanding what you want exactly and missing the target :wink:

1 Like

Oops , sorry , I missed this statement .
Yes your example works perfectly .

Thanks

PaulOB ;
I have a related question :
Is there a way to force the 1st row 2nd column to expand in accordance to what is in the 1st row 1st column , or vice-versa?
Thanks

    <!DOCTYPE html>
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
     <title></title>
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <style type="text/css">
    .grid-container {
      display: grid;
      grid-template-columns: minmax(100px, 50%) minmax(100px, 50%);
      grid-template-areas: "grid1 grid2";
      grid-gap: 4px;
      background-color: #2196f3;
    //  padding: 10px;
      justify-content: center;
    }
    .grid-container > div {
      text-align: center;
      font-size: 16px;
    }
    .item1,
    .item2 {
      grid-area: grid1;
      display: grid;
      grid-template-rows: 1fr;
    }
    .item2 {
      grid-area: grid2;
    }
    .inner {
      background-color: rgba(255, 255, 255, 0.8);
      padding: 20px 0;
      margin: 0 0 10px;
    }
    .inner:last-child {
      margin-bottom: 0;
    }

    </style>
    </head>
    
    <body style="background-color:#EbE8E4; font-family: Tahoma; font-size:18px; color:black;"> 
    
    <div class="grid-container">
      <div class="item1">
        <div class="inner">1) Col 1 row 1
    	<br>test
    	<br>test
    	<br>test
    	<br>test
    	<br>test
    	  </div>
        <div class="inner">2) Col 1 row 2</div>
        <div class="inner">3) Col 1 row 3</div>
      </div>
      <div class="item2">
        <div class="inner">4) Col 2 row 1</div>
        <div class="inner">5) Col 2 row 2</div>
        <div class="inner">6) Col 2 row 3
    	<br>test
    	<br>test
    	        <br>test
                
    	        </div>
                </div>
                </div>
                
        </body>
![Col-Row-MissMatch-400x205|400x205](upload://4FA8glSTbdjyvIINEF3nVHXHSuJ.png)

You mean like this?

1 Like

Yes
exactly like that .
Thank you very much !
Thanks for the jump start .
I am studying Html-Grids here and elsewhere :
https://www.youtube.com/watch?v=x7tLPhnA06w&list=PL4cUxeGkcC9itC4TxYMzFCfveyutyPOCY&index=1

PaulOB
Is there a shortcut way to handle a large number of grid items ?
I’ll end up having two columns with 128 cells each .

Thanks

That’s a good question and one that seems to defeat me at the moment. :slight_smile:

My CSS grid skills are pretty basic I can usually do most of the stuff I want without grid and when I find something complex I want to try then grid can’t seem to do it either :slight_smile:

It seems as though you would need the new CSS subgrid option which will allow the nested grid columns to maintain alignment but browser support is sparse at the moment.

The only option I can think of at the moment to simplify things is when you output the html (! assume you are doing this from a database or generating automatically somewhere) is that you directly write a style attribute into the html and apply the order property.

This would entail counting the items in the list and then applying odd numbers to the first half of results and even numbers to the second half of results. This would result in this codepen.

The css is simplified but the html has the order property written directly into the tag.

<div class="grid-container">
  <div style="order:1">1) Col 1 row 1<br>
    test<br>
    test<br>
    test</div>
  <div style="order:3">2) Col 1 row 2</div>
  <div style="order:5">3) Col 1 row 3<br>
    test<br>
    test</div>
  <div style="order:7">4) Col 1 row 4</div>
  <div style="order:9">5) Col 1 row 5<br>
    test<br>
    test</div>
  <div style="order:11">6) Col 1 row 6</div>
  <div style="order:2">7) Col 2 row 1<br>
    test</div>
  <div style="order:4">8) Col 2 row 2<br>
    test<br>
  </div>
  <div style="order:6">9) Col 2 row 3<br>
    test<br>
    <br>
    test<br>
    test</div>
  <div style="order:8">10) Col 2 row 4</div>
  <div style="order:10">11) Col 2 row 5<br>
    test<br>
    test <br>
    test<br>
    test</div>
  <div style="order:12">12) Col 2 row 6</div>
</div>

If you can’t do that automatically from the back-end then I’m sure one of the JS experts here could duplicate that effect in js without too much trouble.

2 Likes

Here’s my attempt at adding the order property with JS. It’s probably a bit simplistic but as proof of concept seems to work.

The html is in order and originally laid out right to left and so on as per normal. The order property then changes the order of the items so that the first half of the list is shown on the left and the second half shown on the right. This allows you to copy the text from one column or the other rather than going from side to side.

Hope it helps anyway.

1 Like

Thanks PaulOB ;
I don’t really understand the .js code ,
so think I’ll stick with the
grid-template-columns: repeat(
auto-fill,
minmax(120px, 50%) minmax(120px, 50%) option .
I like its compactability (number of lines of code).
But the prob with the ‘auto-fill’ code is that it looses its "individual column selectability’’ .

Is there a way to keep ‘auto-fill’ and also have ''individual column selectability" ?

Again , Thanks for all your help !

No I’m afraid not because you are asking the browser to select something that is not in order of the html. The highlighting of text must follow the html and not the display you see on the screen.

That’s why my examples have the correct html order but then css moved them out of position and into columns.

The JS example is the most concise of all those methods and the one I would go with. The JS counts the number of elements in question and then directly applies the css order property in such an order that the first half of the list appears on the right and the second half appears on the left.

The html and CSS for the js example is the simplest also and easier to undertsand.

I don’t see any other alternatives at the moment that will work as well as that method (although I never say never).:slight_smile:

2 Likes

Ok ,Thanks ;
I tested out with and without the .js .
The results are the same .
I don’t see how the .js gets called at any time .
Thanks

Try again, the results are completely different. :slight_smile:

With JS the numbers go down the left column first (1,2,3,4,5,6,) and then down the right column you get (7,8,9,10,11,12).
i.e.
1 - 7
2 - 8
3 - 9
4 - 10
5 - 11
6 - 12

With js removed you would get the horizontal wrapping.

i,e,

1 - 2
3 - 4
5 - 6
7 - 8
9 - 10
11 - 12

Here’s a screenshot showing with and without JS.

Note that both screenshots are using the same html and css. I have just removed the JS from the second one.

The JS in the codepen is in the right panel of the codepen. It is akin to having the JS in a script tag at the end of the html just before the closing body tag but after all other content.

Th js automatically runs when the document is loaded and counts how many elements you have and sets the css so that the elements appear to be in column while in fact the html is still in the original left to right order. This is how you are able to highlight each column rather than highlighting the whole page as you move down.

If you were to look at the source code in your devtools panel you will see that the html looks different becuse the js has added the inline css just like this.

<div class="grid-container">
<div style="order: 1;">1) Col 1 row 1<br>
test<br>
test<br>
test</div>
<div style="order: 3;">2) Col 1 row 2</div>
<div style="order: 5;">3) Col 1 row 3<br>
test<br>
test</div>
<div style="order: 7;">4) Col 1 row 4</div>
<div style="order: 9;">5) Col 1 row 5<br>
test<br>
test</div>
<div style="order: 11;">6) Col 1 row 6 <br>test</div>
<div style="order: 2;">7) Col 2 row 1<br>
test</div>
<div style="order: 4;">8) Col 2 row 2<br>
test<br>
</div>
<div style="order: 6;">9) Col 2 row 3<br>
test<br>
<br>
test<br>
test</div>
<div style="order: 8;">10) Col 2 row 4</div>
<div style="order: 10;">11) Col 2 row 5<br>
test<br>
test <br>
test<br>
test</div>
<div style="order: 12;">12) Col 2 row 6</div>
</div>

You can see that the order property has been added a style attribute to the html.

style="order: 12;
e.g.

<div style="order: 12;">12) Col 2 row 6</div>

If you view the actual source in the codepen itself you will not see that style attribute. You would see this for that last item.

<div>12) Col 2 row 6</div>

Hope that was what you were asking unless you meant you wanted to know the specifics of the JS itself?

2 Likes

Thanks PaulOB ;
Oops , Sorry !
I put your js in the wrong place .

Your js is super cool .
I thought I could exchange
this “minmax(120px, 50%) minmax(120px, 50%)”
with this “minmax(120px, 30%) minmax(120px, 30%) minmax(120px, 30%)” . But nogo .

As I am learning about css-Grid ,I was thinking of writing a “grid maker program” (in pureBasic) ,
but with your concise code , maybe I won’t need to .

What code changes would I have to make in order to create more columns using your js code , and still using the original 12 DivCells ?

I have written some novice Html/Css/Js before , but it was a while ago , and Css-Grid is new to me .
http://vmars.us/My-Favorite-Html-Created-By-Me/FreshDraft-SaveLoadFile-PERFECT.html

Thanks

Yes that would work for 3 columns.

minmax(120px, 33.3%) minmax(120px, 33.3%) minmax(120px, 33.3%)

However you would need to change the JS.

I mentioned above that the the logic of the JS in that it counts the divs in the html and then divides that amount by 2 to get 2 columns and then applies the css appropriately.

If you wanted 3 columns then the JS would need to be adjusted to divide by 3 and distribute the inline css accordingly.

Here’s the 3 column version.

Note that the JS is assuming that the divs available are exactly divisible by 3. If for example you only output 11 divs then there is no error checking in the JS to account for this. You would need to build in some error checking or at least make sure that the back end of your application always outputs an even number of columns (or outputs some dummy elements to keep the columns even).

2 Likes

Ahh , Ok , I get it now !
Thanks Paul :grinning:

1 Like