Browse code

Add a grid placement wrapper content element

Benjamin Roth authored on01/03/2025 21:22:53
Showing8 changed files
... ...
@@ -19,7 +19,7 @@ $GLOBALS['TL_DCA']['tl_content']['palettes']['background_wrapper'] = '
19 19
 
20 20
 $GLOBALS['TL_DCA']['tl_content']['palettes']['grid_placement_wrapper'] = '
21 21
     {type_legend},type,headline;
22
-    {grid_placement_legend},vr_gpw_grid;
22
+    {grid_placement_legend},vr_gpw_grid,vr_gpw_tablet_grid,vr_gpw_mobile_grid;
23 23
     {template_legend:hide},customTpl;
24 24
     {protected_legend:hide},protected;
25 25
     {expert_legend:hide},cssID;
... ...
@@ -233,3 +233,25 @@ $GLOBALS['TL_DCA']['tl_content']['fields']['vr_gpw_grid'] = [
233 233
     ],
234 234
     'sql' => "text NULL",
235 235
 ];
236
+
237
+$GLOBALS['TL_DCA']['tl_content']['fields']['vr_gpw_tablet_grid'] = [
238
+    'exclude' => true,
239
+    'inputType' => 'gridPosition',
240
+    'eval'      => [
241
+        'tl_class' => 'clr',
242
+        'cols' => 12,
243
+        'rows' => 6,
244
+    ],
245
+    'sql' => "text NULL",
246
+];
247
+
248
+$GLOBALS['TL_DCA']['tl_content']['fields']['vr_gpw_mobile_grid'] = [
249
+    'exclude' => true,
250
+    'inputType' => 'gridPosition',
251
+    'eval'      => [
252
+        'tl_class' => 'clr',
253
+        'cols' => 12,
254
+        'rows' => 6,
255
+    ],
256
+    'sql' => "text NULL",
257
+];
... ...
@@ -142,12 +142,28 @@
142 142
             </trans-unit>
143 143
 
144 144
             <trans-unit id="tl_content.vr_gpw_grid.0">
145
-                <source>Define placement</source>
146
-                <target>Platzierung definieren</target>
145
+                <source>Define desktop placement</source>
146
+                <target>Desktop-Platzierung definieren</target>
147 147
             </trans-unit>
148 148
             <trans-unit id="tl_content.vr_gpw_grid.1">
149
-                <source>Define the position of nested fragments in the grid. Select a single cell or a rectangle of multiple cells.</source>
150
-                <target>Die Position verschachtelter Fragmente im Raster definieren. Wählen Sie eine einzelne Zelle oder ein Rechteck mit mehreren Zellen aus.</target>
149
+                <source>Define the desktop position of nested fragments in the grid. Select a single cell or a rectangle of multiple cells.</source>
150
+                <target>Die Dektop-Position verschachtelter Fragmente im Raster definieren. Wählen Sie eine einzelne Zelle oder ein Rechteck mit mehreren Zellen aus.</target>
151
+            </trans-unit>
152
+            <trans-unit id="tl_content.vr_gpw_tablet_grid.0">
153
+                <source>Define tablet placement</source>
154
+                <target>Tablet-Platzierung definieren</target>
155
+            </trans-unit>
156
+            <trans-unit id="tl_content.vr_gpw_mobile_grid.1">
157
+                <source>Define the tablet position of nested fragments in the grid. Select a single cell or a rectangle of multiple cells.</source>
158
+                <target>Die Tablet-Position verschachtelter Fragmente im Raster definieren. Wählen Sie eine einzelne Zelle oder ein Rechteck mit mehreren Zellen aus.</target>
159
+            </trans-unit>
160
+            <trans-unit id="tl_content.vr_gpw_mobile_grid.0">
161
+                <source>Define mobile placement</source>
162
+                <target>Mobile-Platzierung definieren</target>
163
+            </trans-unit>
164
+            <trans-unit id="tl_content.vr_gpw_grid.1">
165
+                <source>Define the mobile position of nested fragments in the grid. Select a single cell or a rectangle of multiple cells.</source>
166
+                <target>Die mobile Position verschachtelter Fragmente im Raster definieren. Wählen Sie eine einzelne Zelle oder ein Rechteck mit mehreren Zellen aus.</target>
151 167
             </trans-unit>
152 168
 
153 169
             <trans-unit id="tl_content.grid_placement_legend">
... ...
@@ -55,10 +55,22 @@
55 55
             </trans-unit>
56 56
 
57 57
             <trans-unit id="tl_content.vr_gpw_grid.0">
58
-                <source>Define placement</source>
58
+                <source>Define desktop placement</source>
59
+            </trans-unit>
60
+            <trans-unit id="tl_content.vr_gpw_tablet_grid.1">
61
+                <source>Define the desktop position of nested fragments in the grid. Select a single cell or a rectangle of multiple cells.</source>
62
+            </trans-unit>
63
+            <trans-unit id="tl_content.vr_gpw_tablet_grid.0">
64
+                <source>Define tablet placement</source>
65
+            </trans-unit>
66
+            <trans-unit id="tl_content.vr_gpw_mobile_grid.1">
67
+                <source>Define the tablet position of nested fragments in the grid. Select a single cell or a rectangle of multiple cells.</source>
68
+            </trans-unit>
69
+            <trans-unit id="tl_content.vr_gpw_mobile_grid.0">
70
+                <source>Define mobile placement</source>
59 71
             </trans-unit>
60 72
             <trans-unit id="tl_content.vr_gpw_grid.1">
61
-                <source>Define the position of nested fragments in the grid. Select a single cell or a rectangle of multiple cells.</source>
73
+                <source>Define the mobile position of nested fragments in the grid. Select a single cell or a rectangle of multiple cells.</source>
62 74
             </trans-unit>
63 75
 
64 76
             <trans-unit id="tl_content.grid_placement_legend">
... ...
@@ -2,5 +2,11 @@
2 2
 {% import "@ContaoCore/Image/Studio/_macros.html.twig" as studio %}
3 3
 
4 4
 {% block content %}
5
-
5
+<div class="grid-placement-wrapper gp--grid-container">
6
+    <div class="grid-placement-content{{ grid_mobile_classes is not empty ? ' ' ~ grid_mobile_classes }}{{ grid_tablet_classes is not empty ? ' ' ~ grid_tablet_classes }}{{ grid_classes is not empty ? ' ' ~ grid_classes }}">
7
+        {% for fragment in nested_fragments %}
8
+            {{ content_element(fragment) }}
9
+        {% endfor %}
10
+    </div>
11
+</div>
6 12
 {% endblock %}
7 13
new file mode 100644
... ...
@@ -0,0 +1,376 @@
1
+:root {
2
+  --grid-columns: 12;
3
+  --grid-rows: 6;
4
+}
5
+
6
+.gp--col-start-1 {
7
+  grid-column-start: 1;
8
+}
9
+
10
+.gp--col-end-2 {
11
+  grid-column-end: 2;
12
+}
13
+
14
+.gp--col-start-2 {
15
+  grid-column-start: 2;
16
+}
17
+
18
+.gp--col-end-3 {
19
+  grid-column-end: 3;
20
+}
21
+
22
+.gp--col-start-3 {
23
+  grid-column-start: 3;
24
+}
25
+
26
+.gp--col-end-4 {
27
+  grid-column-end: 4;
28
+}
29
+
30
+.gp--col-start-4 {
31
+  grid-column-start: 4;
32
+}
33
+
34
+.gp--col-end-5 {
35
+  grid-column-end: 5;
36
+}
37
+
38
+.gp--col-start-5 {
39
+  grid-column-start: 5;
40
+}
41
+
42
+.gp--col-end-6 {
43
+  grid-column-end: 6;
44
+}
45
+
46
+.gp--col-start-6 {
47
+  grid-column-start: 6;
48
+}
49
+
50
+.gp--col-end-7 {
51
+  grid-column-end: 7;
52
+}
53
+
54
+.gp--col-start-7 {
55
+  grid-column-start: 7;
56
+}
57
+
58
+.gp--col-end-8 {
59
+  grid-column-end: 8;
60
+}
61
+
62
+.gp--col-start-8 {
63
+  grid-column-start: 8;
64
+}
65
+
66
+.gp--col-end-9 {
67
+  grid-column-end: 9;
68
+}
69
+
70
+.gp--col-start-9 {
71
+  grid-column-start: 9;
72
+}
73
+
74
+.gp--col-end-10 {
75
+  grid-column-end: 10;
76
+}
77
+
78
+.gp--col-start-10 {
79
+  grid-column-start: 10;
80
+}
81
+
82
+.gp--col-end-11 {
83
+  grid-column-end: 11;
84
+}
85
+
86
+.gp--col-start-11 {
87
+  grid-column-start: 11;
88
+}
89
+
90
+.gp--col-end-12 {
91
+  grid-column-end: 12;
92
+}
93
+
94
+.gp--col-start-12 {
95
+  grid-column-start: 12;
96
+}
97
+
98
+.gp--col-end-13 {
99
+  grid-column-end: 13;
100
+}
101
+
102
+.gp--row-start-1 {
103
+  grid-row-start: 1;
104
+}
105
+
106
+.gp--row-end-2 {
107
+  grid-row-end: 2;
108
+}
109
+
110
+.gp--row-start-2 {
111
+  grid-row-start: 2;
112
+}
113
+
114
+.gp--row-end-3 {
115
+  grid-row-end: 3;
116
+}
117
+
118
+.gp--row-start-3 {
119
+  grid-row-start: 3;
120
+}
121
+
122
+.gp--row-end-4 {
123
+  grid-row-end: 4;
124
+}
125
+
126
+.gp--row-start-4 {
127
+  grid-row-start: 4;
128
+}
129
+
130
+.gp--row-end-5 {
131
+  grid-row-end: 5;
132
+}
133
+
134
+.gp--row-start-5 {
135
+  grid-row-start: 5;
136
+}
137
+
138
+.gp--row-end-6 {
139
+  grid-row-end: 6;
140
+}
141
+
142
+.gp--row-start-6 {
143
+  grid-row-start: 6;
144
+}
145
+
146
+.gp--row-end-7 {
147
+  grid-row-end: 7;
148
+}
149
+
150
+@media (max-width: 900px) {
151
+  .gp--col-tablet-start-1 {
152
+    grid-column-start: 1;
153
+  }
154
+  .gp--col-tablet-end-2 {
155
+    grid-column-end: 2;
156
+  }
157
+  .gp--col-tablet-start-2 {
158
+    grid-column-start: 2;
159
+  }
160
+  .gp--col-tablet-end-3 {
161
+    grid-column-end: 3;
162
+  }
163
+  .gp--col-tablet-start-3 {
164
+    grid-column-start: 3;
165
+  }
166
+  .gp--col-tablet-end-4 {
167
+    grid-column-end: 4;
168
+  }
169
+  .gp--col-tablet-start-4 {
170
+    grid-column-start: 4;
171
+  }
172
+  .gp--col-tablet-end-5 {
173
+    grid-column-end: 5;
174
+  }
175
+  .gp--col-tablet-start-5 {
176
+    grid-column-start: 5;
177
+  }
178
+  .gp--col-tablet-end-6 {
179
+    grid-column-end: 6;
180
+  }
181
+  .gp--col-tablet-start-6 {
182
+    grid-column-start: 6;
183
+  }
184
+  .gp--col-tablet-end-7 {
185
+    grid-column-end: 7;
186
+  }
187
+  .gp--col-tablet-start-7 {
188
+    grid-column-start: 7;
189
+  }
190
+  .gp--col-tablet-end-8 {
191
+    grid-column-end: 8;
192
+  }
193
+  .gp--col-tablet-start-8 {
194
+    grid-column-start: 8;
195
+  }
196
+  .gp--col-tablet-end-9 {
197
+    grid-column-end: 9;
198
+  }
199
+  .gp--col-tablet-start-9 {
200
+    grid-column-start: 9;
201
+  }
202
+  .gp--col-tablet-end-10 {
203
+    grid-column-end: 10;
204
+  }
205
+  .gp--col-tablet-start-10 {
206
+    grid-column-start: 10;
207
+  }
208
+  .gp--col-tablet-end-11 {
209
+    grid-column-end: 11;
210
+  }
211
+  .gp--col-tablet-start-11 {
212
+    grid-column-start: 11;
213
+  }
214
+  .gp--col-tablet-end-12 {
215
+    grid-column-end: 12;
216
+  }
217
+  .gp--col-tablet-start-12 {
218
+    grid-column-start: 12;
219
+  }
220
+  .gp--col-tablet-end-13 {
221
+    grid-column-end: 13;
222
+  }
223
+  .gp--row-tablet-start-1 {
224
+    grid-row-start: 1;
225
+  }
226
+  .gp--row-tablet-end-2 {
227
+    grid-row-end: 2;
228
+  }
229
+  .gp--row-tablet-start-2 {
230
+    grid-row-start: 2;
231
+  }
232
+  .gp--row-tablet-end-3 {
233
+    grid-row-end: 3;
234
+  }
235
+  .gp--row-tablet-start-3 {
236
+    grid-row-start: 3;
237
+  }
238
+  .gp--row-tablet-end-4 {
239
+    grid-row-end: 4;
240
+  }
241
+  .gp--row-tablet-start-4 {
242
+    grid-row-start: 4;
243
+  }
244
+  .gp--row-tablet-end-5 {
245
+    grid-row-end: 5;
246
+  }
247
+  .gp--row-tablet-start-5 {
248
+    grid-row-start: 5;
249
+  }
250
+  .gp--row-tablet-end-6 {
251
+    grid-row-end: 6;
252
+  }
253
+  .gp--row-tablet-start-6 {
254
+    grid-row-start: 6;
255
+  }
256
+  .gp--row-tablet-end-7 {
257
+    grid-row-end: 7;
258
+  }
259
+}
260
+@media (max-width: 599px) {
261
+  .gp--col-mobil-start-1 {
262
+    grid-column-start: 1;
263
+  }
264
+  .gp--col-mobil-end-2 {
265
+    grid-column-end: 2;
266
+  }
267
+  .gp--col-mobil-start-2 {
268
+    grid-column-start: 2;
269
+  }
270
+  .gp--col-mobil-end-3 {
271
+    grid-column-end: 3;
272
+  }
273
+  .gp--col-mobil-start-3 {
274
+    grid-column-start: 3;
275
+  }
276
+  .gp--col-mobil-end-4 {
277
+    grid-column-end: 4;
278
+  }
279
+  .gp--col-mobil-start-4 {
280
+    grid-column-start: 4;
281
+  }
282
+  .gp--col-mobil-end-5 {
283
+    grid-column-end: 5;
284
+  }
285
+  .gp--col-mobil-start-5 {
286
+    grid-column-start: 5;
287
+  }
288
+  .gp--col-mobil-end-6 {
289
+    grid-column-end: 6;
290
+  }
291
+  .gp--col-mobil-start-6 {
292
+    grid-column-start: 6;
293
+  }
294
+  .gp--col-mobil-end-7 {
295
+    grid-column-end: 7;
296
+  }
297
+  .gp--col-mobil-start-7 {
298
+    grid-column-start: 7;
299
+  }
300
+  .gp--col-mobil-end-8 {
301
+    grid-column-end: 8;
302
+  }
303
+  .gp--col-mobil-start-8 {
304
+    grid-column-start: 8;
305
+  }
306
+  .gp--col-mobil-end-9 {
307
+    grid-column-end: 9;
308
+  }
309
+  .gp--col-mobil-start-9 {
310
+    grid-column-start: 9;
311
+  }
312
+  .gp--col-mobil-end-10 {
313
+    grid-column-end: 10;
314
+  }
315
+  .gp--col-mobil-start-10 {
316
+    grid-column-start: 10;
317
+  }
318
+  .gp--col-mobil-end-11 {
319
+    grid-column-end: 11;
320
+  }
321
+  .gp--col-mobil-start-11 {
322
+    grid-column-start: 11;
323
+  }
324
+  .gp--col-mobil-end-12 {
325
+    grid-column-end: 12;
326
+  }
327
+  .gp--col-mobil-start-12 {
328
+    grid-column-start: 12;
329
+  }
330
+  .gp--col-mobil-end-13 {
331
+    grid-column-end: 13;
332
+  }
333
+  .gp--row-mobil-start-1 {
334
+    grid-row-start: 1;
335
+  }
336
+  .gp--row-mobil-end-2 {
337
+    grid-row-end: 2;
338
+  }
339
+  .gp--row-mobil-start-2 {
340
+    grid-row-start: 2;
341
+  }
342
+  .gp--row-mobil-end-3 {
343
+    grid-row-end: 3;
344
+  }
345
+  .gp--row-mobil-start-3 {
346
+    grid-row-start: 3;
347
+  }
348
+  .gp--row-mobil-end-4 {
349
+    grid-row-end: 4;
350
+  }
351
+  .gp--row-mobil-start-4 {
352
+    grid-row-start: 4;
353
+  }
354
+  .gp--row-mobil-end-5 {
355
+    grid-row-end: 5;
356
+  }
357
+  .gp--row-mobil-start-5 {
358
+    grid-row-start: 5;
359
+  }
360
+  .gp--row-mobil-end-6 {
361
+    grid-row-end: 6;
362
+  }
363
+  .gp--row-mobil-start-6 {
364
+    grid-row-start: 6;
365
+  }
366
+  .gp--row-mobil-end-7 {
367
+    grid-row-end: 7;
368
+  }
369
+}
370
+.gp--grid-container {
371
+  display: grid;
372
+  grid-template-columns: repeat(var(--grid-columns), minmax(0px, 1fr));
373
+  grid-template-rows: repeat(var(--grid-rows), minmax(0px, auto));
374
+  position: absolute;
375
+  inset: 0;
376
+}
0 377
new file mode 100644
... ...
@@ -0,0 +1 @@
1
+:root{--grid-columns:12;--grid-rows:6}.gp--col-start-1{grid-column-start:1}.gp--col-end-2{grid-column-end:2}.gp--col-start-2{grid-column-start:2}.gp--col-end-3{grid-column-end:3}.gp--col-start-3{grid-column-start:3}.gp--col-end-4{grid-column-end:4}.gp--col-start-4{grid-column-start:4}.gp--col-end-5{grid-column-end:5}.gp--col-start-5{grid-column-start:5}.gp--col-end-6{grid-column-end:6}.gp--col-start-6{grid-column-start:6}.gp--col-end-7{grid-column-end:7}.gp--col-start-7{grid-column-start:7}.gp--col-end-8{grid-column-end:8}.gp--col-start-8{grid-column-start:8}.gp--col-end-9{grid-column-end:9}.gp--col-start-9{grid-column-start:9}.gp--col-end-10{grid-column-end:10}.gp--col-start-10{grid-column-start:10}.gp--col-end-11{grid-column-end:11}.gp--col-start-11{grid-column-start:11}.gp--col-end-12{grid-column-end:12}.gp--col-start-12{grid-column-start:12}.gp--col-end-13{grid-column-end:13}.gp--row-start-1{grid-row-start:1}.gp--row-end-2{grid-row-end:2}.gp--row-start-2{grid-row-start:2}.gp--row-end-3{grid-row-end:3}.gp--row-start-3{grid-row-start:3}.gp--row-end-4{grid-row-end:4}.gp--row-start-4{grid-row-start:4}.gp--row-end-5{grid-row-end:5}.gp--row-start-5{grid-row-start:5}.gp--row-end-6{grid-row-end:6}.gp--row-start-6{grid-row-start:6}.gp--row-end-7{grid-row-end:7}@media (max-width:900px){.gp--col-tablet-start-1{grid-column-start:1}.gp--col-tablet-end-2{grid-column-end:2}.gp--col-tablet-start-2{grid-column-start:2}.gp--col-tablet-end-3{grid-column-end:3}.gp--col-tablet-start-3{grid-column-start:3}.gp--col-tablet-end-4{grid-column-end:4}.gp--col-tablet-start-4{grid-column-start:4}.gp--col-tablet-end-5{grid-column-end:5}.gp--col-tablet-start-5{grid-column-start:5}.gp--col-tablet-end-6{grid-column-end:6}.gp--col-tablet-start-6{grid-column-start:6}.gp--col-tablet-end-7{grid-column-end:7}.gp--col-tablet-start-7{grid-column-start:7}.gp--col-tablet-end-8{grid-column-end:8}.gp--col-tablet-start-8{grid-column-start:8}.gp--col-tablet-end-9{grid-column-end:9}.gp--col-tablet-start-9{grid-column-start:9}.gp--col-tablet-end-10{grid-column-end:10}.gp--col-tablet-start-10{grid-column-start:10}.gp--col-tablet-end-11{grid-column-end:11}.gp--col-tablet-start-11{grid-column-start:11}.gp--col-tablet-end-12{grid-column-end:12}.gp--col-tablet-start-12{grid-column-start:12}.gp--col-tablet-end-13{grid-column-end:13}.gp--row-tablet-start-1{grid-row-start:1}.gp--row-tablet-end-2{grid-row-end:2}.gp--row-tablet-start-2{grid-row-start:2}.gp--row-tablet-end-3{grid-row-end:3}.gp--row-tablet-start-3{grid-row-start:3}.gp--row-tablet-end-4{grid-row-end:4}.gp--row-tablet-start-4{grid-row-start:4}.gp--row-tablet-end-5{grid-row-end:5}.gp--row-tablet-start-5{grid-row-start:5}.gp--row-tablet-end-6{grid-row-end:6}.gp--row-tablet-start-6{grid-row-start:6}.gp--row-tablet-end-7{grid-row-end:7}}@media (max-width:599px){.gp--col-mobil-start-1{grid-column-start:1}.gp--col-mobil-end-2{grid-column-end:2}.gp--col-mobil-start-2{grid-column-start:2}.gp--col-mobil-end-3{grid-column-end:3}.gp--col-mobil-start-3{grid-column-start:3}.gp--col-mobil-end-4{grid-column-end:4}.gp--col-mobil-start-4{grid-column-start:4}.gp--col-mobil-end-5{grid-column-end:5}.gp--col-mobil-start-5{grid-column-start:5}.gp--col-mobil-end-6{grid-column-end:6}.gp--col-mobil-start-6{grid-column-start:6}.gp--col-mobil-end-7{grid-column-end:7}.gp--col-mobil-start-7{grid-column-start:7}.gp--col-mobil-end-8{grid-column-end:8}.gp--col-mobil-start-8{grid-column-start:8}.gp--col-mobil-end-9{grid-column-end:9}.gp--col-mobil-start-9{grid-column-start:9}.gp--col-mobil-end-10{grid-column-end:10}.gp--col-mobil-start-10{grid-column-start:10}.gp--col-mobil-end-11{grid-column-end:11}.gp--col-mobil-start-11{grid-column-start:11}.gp--col-mobil-end-12{grid-column-end:12}.gp--col-mobil-start-12{grid-column-start:12}.gp--col-mobil-end-13{grid-column-end:13}.gp--row-mobil-start-1{grid-row-start:1}.gp--row-mobil-end-2{grid-row-end:2}.gp--row-mobil-start-2{grid-row-start:2}.gp--row-mobil-end-3{grid-row-end:3}.gp--row-mobil-start-3{grid-row-start:3}.gp--row-mobil-end-4{grid-row-end:4}.gp--row-mobil-start-4{grid-row-start:4}.gp--row-mobil-end-5{grid-row-end:5}.gp--row-mobil-start-5{grid-row-start:5}.gp--row-mobil-end-6{grid-row-end:6}.gp--row-mobil-start-6{grid-row-start:6}.gp--row-mobil-end-7{grid-row-end:7}}.gp--grid-container{display:grid;grid-template-columns:repeat(var(--grid-columns),minmax(0,1fr));grid-template-rows:repeat(var(--grid-rows),minmax(0,auto));position:absolute;inset:0}
0 2
\ No newline at end of file
1 3
new file mode 100644
... ...
@@ -0,0 +1,78 @@
1
+:root {
2
+  --grid-columns: 12;
3
+  --grid-rows: 6;
4
+}
5
+
6
+$grid-columns: 12;
7
+$grid-rows: 6;
8
+
9
+// Default (Desktop)
10
+@for $i from 1 through $grid-columns {
11
+  .gp--col-start-#{$i} {
12
+    grid-column-start: $i;
13
+  }
14
+  .gp--col-end-#{$i + 1} {
15
+    grid-column-end: $i + 1;
16
+  }
17
+}
18
+
19
+@for $i from 1 through $grid-rows {
20
+  .gp--row-start-#{$i} {
21
+    grid-row-start: $i;
22
+  }
23
+  .gp--row-end-#{$i + 1} {
24
+    grid-row-end: $i + 1;
25
+  }
26
+}
27
+
28
+// Tablet (max-width: 900px)
29
+@media (max-width: 900px) {
30
+  @for $i from 1 through $grid-columns {
31
+    .gp--col-tablet-start-#{$i} {
32
+      grid-column-start: $i;
33
+    }
34
+    .gp--col-tablet-end-#{$i + 1} {
35
+      grid-column-end: $i + 1;
36
+    }
37
+  }
38
+
39
+  @for $i from 1 through $grid-rows {
40
+    .gp--row-tablet-start-#{$i} {
41
+      grid-row-start: $i;
42
+    }
43
+    .gp--row-tablet-end-#{$i + 1} {
44
+      grid-row-end: $i + 1;
45
+    }
46
+  }
47
+}
48
+
49
+// Mobil (max-width: 599px)
50
+@media (max-width: 599px) {
51
+  @for $i from 1 through $grid-columns {
52
+    .gp--col-mobil-start-#{$i} {
53
+      grid-column-start: $i;
54
+    }
55
+    .gp--col-mobil-end-#{$i + 1} {
56
+      grid-column-end: $i + 1;
57
+    }
58
+  }
59
+
60
+  @for $i from 1 through $grid-rows {
61
+    .gp--row-mobil-start-#{$i} {
62
+      grid-row-start: $i;
63
+    }
64
+    .gp--row-mobil-end-#{$i + 1} {
65
+      grid-row-end: $i + 1;
66
+    }
67
+  }
68
+}
69
+
70
+
71
+// Anpassen des Containers
72
+.gp--grid-container {
73
+  display: grid;
74
+  grid-template-columns: repeat(var(--grid-columns), minmax(0px, 1fr));
75
+  grid-template-rows: repeat(var(--grid-rows), minmax(0px, auto));
76
+  position: absolute;
77
+  inset: 0;
78
+}
... ...
@@ -18,7 +18,90 @@ class GridPlacementWrapperController extends AbstractContentElementController
18 18
 {
19 19
     protected function getResponse(FragmentTemplate $template, ContentModel $model, Request $request): Response
20 20
     {
21
+        if (System::getContainer()->get('contao.routing.scope_matcher')->isFrontendRequest($request))
22
+        {
23
+            $GLOBALS['TL_CSS'][] = 'bundles/vonrotenbergcoretools/css/grid-placement-wrapper.min.css|static';
24
+        }
21 25
 
26
+        // Sicherstellen, dass alle notwendigen Felder vorhanden sind
27
+        // Desktop Grid
28
+        $gridCells = $model->vr_gpw_grid ? json_decode($model->vr_gpw_grid) : [];
29
+        $intCellStart = !empty($gridCells) ? min($gridCells) : 12;
30
+        $intCellEnd = !empty($gridCells) ? max($gridCells) : 12;
31
+
32
+        // Tablet Grid
33
+        $tabletGridCells = $model->vr_gpw_tablet_grid ? json_decode($model->vr_gpw_tablet_grid) : [];
34
+        $tabletCellStart = !empty($tabletGridCells) ? min($tabletGridCells) : 12;
35
+        $tabletCellEnd = !empty($tabletGridCells) ? max($tabletGridCells) : 12;
36
+
37
+        // Mobile Grid
38
+        $mobileGridCells = $model->vr_gpw_mobile_grid ? json_decode($model->vr_gpw_mobile_grid) : [];
39
+        $mobileCellStart = !empty($mobileGridCells) ? min($mobileGridCells) : 12;
40
+        $mobileCellEnd = !empty($mobileGridCells) ? max($mobileGridCells) : 12;
41
+
42
+
43
+        // Vorbereiten der Daten, inklusive der neuen Tablet- und Mobile-Klassen
44
+        $arrData = array_merge($template->getData(), [
45
+            'colStart' => $this->getColumnNumber(12, $intCellStart),
46
+            'colEnd' => $this->getColumnNumber(12, $intCellEnd),
47
+            'rowStart' => $this->getRowNumber(12, $intCellStart),
48
+            'rowEnd' => $this->getRowNumber(12, $intCellEnd),
49
+            'grid_classes' => $this->getGridClasses(12, $intCellStart, $intCellEnd), // Desktop-Klassen
50
+
51
+            // Spezifische Grid-Klassen für Tablet und Mobile
52
+            'grid_tablet_classes' => count($tabletGridCells) ? $this->getGridClasses(12, $tabletCellStart, $tabletCellEnd, 'tablet') : '',
53
+            'grid_mobile_classes' => count($mobileGridCells) ? $this->getGridClasses(12, $mobileCellStart, $mobileCellEnd, 'mobil') : '',
54
+        ]);
55
+
56
+        $template->setData($arrData);
22 57
         return $template->getResponse();
23 58
     }
59
+
60
+
61
+    private function getColumnNumber(int $columns, int $cellIndex): int
62
+    {
63
+        if ($columns <= 0)
64
+        {
65
+            throw new \InvalidArgumentException('The number of columns must be greater than zero.');
66
+        }
67
+
68
+        return ($cellIndex % $columns) + 1;
69
+    }
70
+
71
+
72
+    private function getRowNumber(int $columns, int $cellIndex): int
73
+    {
74
+        if ($columns <= 0)
75
+        {
76
+            throw new \InvalidArgumentException('The number of columns must be greater than zero.');
77
+        }
78
+
79
+        return intdiv($cellIndex, $columns) + 1;
80
+    }
81
+
82
+    private function getGridClasses(int $columns, int $intCellStart, int $intCellEnd, string $strViewportName = ''): string
83
+    {
84
+        // Berechnung der Start-/Endspalten
85
+        $colStart = $this->getColumnNumber($columns, $intCellStart);
86
+        $colEnd = $this->getColumnNumber($columns, $intCellEnd);
87
+
88
+        // Berechnung der Start-/Endreihen
89
+        $rowStart = $this->getRowNumber($columns, $intCellStart);
90
+        $rowEnd = $this->getRowNumber($columns, $intCellEnd);
91
+
92
+        // Generierung der CSS-Klassennamen
93
+        if (!empty($strViewportName))
94
+        {
95
+            $strViewportName = '-' . $strViewportName;
96
+        }
97
+        $cssClasses = [
98
+            "gp--col$strViewportName-start-$colStart",
99
+            "gp--col$strViewportName-end-" . ($colEnd + 1),    // col-end benötigt +1 gemäß Ihrer CSS-Definition
100
+            "gp--row$strViewportName-start-$rowStart",
101
+            "gp--row$strViewportName-end-" . ($rowEnd + 1),   // row-end benötigt ebenfalls +1
102
+        ];
103
+
104
+        // Klassennamen als String trennen
105
+        return implode(' ', $cssClasses);
106
+    }
24 107
 }