CSS property 'resize' doesn't work with 'sticky' - css

I've created a grid-based table replacement.
The grid is meant to keep table headers on the top when scrolling, for that I've utilized position: sticky;.
While it works flawlessly, it doesn't seem to care if I set resize: horizontal; on it, it just won't let me - I can have either, but not both.
Is there a workaround? Sorry if I don't post the HTML code, it's generated by vue and it's rather unreadable, plus I would have to post vue component contents.
Here's SASS thought:
.table {
display: grid;
overflow-y: scroll;
grid-template-columns: repeat(var(--columnCount), minmax(min-content, 1fr));
max-height: 100px;
}
.table-headers {
display: contents;
top: 0;
}
.table-headers > .table-header:last-of-type > .table-header-resizer {
display: none;
}
.table-header {
top: 0;
display: flex;
position: sticky;
font-weight: 700;
border-right: 1px solid #D5E3EA;
text-overflow: ellipsis;
white-space: nowrap;
border-bottom: 1px solid #D5E3EA;
background: #F7F7F7;
}
.table-header:last-of-type {
border-right: none;
}
.table-header-cell {
display: flex;
flex-grow: 1;
resize: horizontal;
padding: 8px;
}
.table-row {
display: contents;
}
.table-row > .table-cell {
background: #f4f4f4;
border-top: 1px solid #D5E3EA;
}
.table-row > .table-cell:nth-of-type(even) {
background: #f2f2f2;
}
.table-cell {
display: flex;
flex-grow: 1;
padding: 8px;
border-right: 1px solid #D5E3EA;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
.table-cell:last-of-type {
border-right: none;
}
<div class="table" style='--columnCount: 3;'>
<div class="table-headers">
<div class="table-header">
<div class="table-cell">
One
</div>
</div>
<div class="table-header">
<div class="table-cell">
Two
</div>
</div>
<div class="table-header">
<div class="table-cell">
Three
</div>
</div>
</div>
<div class="table-row">
<div class="table-cell">
One
</div>
<div class="table-cell">
Two
</div>
<div class="table-cell">
Three
</div>
</div>
<div class="table-row">
<div class="table-cell">
One
</div>
<div class="table-cell">
Two
</div>
<div class="table-cell">
Three
</div>
</div>
<div class="table-row">
<div class="table-cell">
One
</div>
<div class="table-cell">
Two
</div>
<div class="table-cell">
Three
</div>
</div>
<div class="table-row">
<div class="table-cell">
One
</div>
<div class="table-cell">
Two
</div>
<div class="table-cell">
Three
</div>
</div>
<div class="table-row">
<div class="table-cell">
One
</div>
<div class="table-cell">
Two
</div>
<div class="table-cell">
Three
</div>
</div>
<div class="table-row">
<div class="table-cell">
One
</div>
<div class="table-cell">
Two
</div>
<div class="table-cell">
Three
</div>
</div>
<div class="table-row">
<div class="table-cell">
One
</div>
<div class="table-cell">
Two
</div>
<div class="table-cell">
Three
</div>
</div>
</div>

If you have the same issue, simply put a nested child inside your sticky element and set resize on it instead.

Related

Push the right aligned element down when the first left element is too long

I'm trying to achieve this, where brown gets pushed down when pink is too long, and pink is dynamically sized based on its text content.
I was only able to achieve this using javascript and two templates, if pink length is over X use second template, but I'm wondering if there's a way to achieve this using CSS only?
I tried meddling with grid auto-fill/auto-fit with minmax, float, flex with wrap, but I couldn't get to the desired result with these.
.parent {
width: 170px;
}
.flex {
display: flex;
}
div {
outline: 2px solid rgba(255, 0,0, 0.3);
}
<div>
<p>scenario A</p>
<div class="parent flex">
<div>
<div class="one">A short title</div>
<div class="three">Some text here</div>
<div class="three">some more text</div>
</div>
<div>
<button>A button</button>
</div>
</div>
</div>
<div>
<p>scenario B</p>
<div class="parent">
<div class="one">Testing a very long title</div>
<div class="flex">
<div>
<div class="three">Some text here</div>
<div class="three">some more text</div>
</div>
<div>
<button>A button</button>
</div>
</div>
</div>
</div>
<p>can a component achieve both a and b with only css?
I found a solution, it requires having fixed height in the first row, and the right side button will basically overflow when needed.
Will wait a bit before accepting my own solution in case someone came with a better one.
.container {
width: 300px;
display: flex;
gap: 10px;
padding: 16px;
font-size: 14px;
font-family: Arial;
}
.text {
flex: 1;
min-width: 0;
}
.first-row {
height: 22px;
display: flex;
flex-wrap: wrap;
justify-content: flex-end;
gap: 8px;
}
.image {
width: 40px;
height: 40px;
border-radius: 50%;
background-color: #444;
}
.title {
flex-grow: 1;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
<h2>Long title</h2>
<div class="container">
<div class="image"></div>
<div class="text">
<div class="first-row">
<div class="title">Test title test title test title</div>
<button>Visit store</button>
</div>
<div class="three">in the stores</div>
<div class="three">sponsored</div>
</div>
</div>
<h2>Short title</h2>
<div class="container">
<div class="image"></div>
<div class="text">
<div class="first-row">
<div class="title">Short title</div>
<button>Visit place</button>
</div>
<div class="three">in the stores</div>
<div class="three">sponsored</div>
</div>
</div>
<h2>Very long title</h2>
<div class="container">
<div class="image"></div>
<div class="text">
<div class="first-row">
<div class="title">Test title test titleTest title test titleTest title test title</div>
<button>Visit place</button>
</div>
<div class="three">in the stores</div>
<div class="three">sponsored</div>
</div>
</div>

remove margin bottom from the last line in wrapped elements

How can I keep the margin-bottom only for the elements that are not in the last line ?
.container {
display: flex;
flex-flow: row wrap;
background: green;
justify-content: space-between;
}
.block {
height: 60px;
max-width: calc((100% - (12px * 2)) / 3);
flex-basis: calc((100% - (12px * 2)) / 3);
background: orange;
box-shadow: inset 0 0 0 3px black;
margin-bottom: 12px;
}
<div class="container">
<div class="block">
</div>
<div class="block">
</div>
<div class="block">
</div>
<div class="block">
</div>
<div class="block">
</div>
<div class="block">
</div>
<div class="block">
</div>
<div class="block">
</div>
<div class="block">
</div>
</div>
Thanks in advance.
This is what you are looking for:
.container .block:nth-last-child(-n+3){
margin-bottom: 0px;
}
for flex and grid, you can use the gap propertie to avoid playing with margins:
https://developer.mozilla.org/en-US/docs/Web/CSS/gap
The gap CSS property sets the gaps (gutters) between rows and columns. It is a shorthand for row-gap and column-gap.
Applies to multi-column elements, flex containers, grid containers
see https://www.caniuse.com/?search=gap for support
to set 3 elements on a line, give a min-width bigger than 25% and set them to grow via flex-grow. for the demo i used 26%, should be small enough to leave room for the gaps .
Demo of your code witout margins but still a gap in between elements
.container {
display: flex;
flex-flow: row wrap;
background: green;
gap: 12px;
/* see https://www.caniuse.com/?search=gap for support */
}
.block {
height: 60px;
flex: 1 1 0; /* or flex:1; */
/* to stretch them at the most and even their sizes*/
min-width: 26%;
/* it cannot be more than 3 on a row */
background: orange;
box-shadow: inset 0 0 0 3px black;
padding:5px; /* padding is fine */
}
<div class="container">
<div class="block">
</div>
<div class="block">
</div>
<div class="block">
</div>
<div class="block">
</div>
<div class="block">
</div>
<div class="block">
</div>
<div class="block">
</div>
<div class="block">
</div>
<div class="block">
</div>
</div>
<hr>
<div class="container">
<div class="block">A single line
</div>
<div class="block">
</div>
<div class="block">
</div>
</div>
<hr>
<div class="container">
<div class="block">
</div>
<div class="block">
</div>
<div class="block">
</div>
<div class="block">a second and last line
</div>
<div class="block">
</div>
<div class="block">
</div>
</div>
<hr>
<div class="container">
<div class="block">2 blocks , is that okay ?
</div>
<div class="block">
</div>
</div>
You can also use CSS grid:
.container {
display: grid;
grid-template-columns:repeat(3,1fr);
grid-gap:12px;
background: green;
}
.block {
height: 60px;
background: orange;
box-shadow: inset 0 0 0 3px black;
}
<div class="container">
<div class="block">
</div>
<div class="block">
</div>
<div class="block">
</div>
<div class="block">
</div>
<div class="block">
</div>
<div class="block">
</div>
<div class="block">
</div>
<div class="block">
</div>
<div class="block">
</div>
</div>

Boostrap 3 css vertical align two divs one top one bottom

Issue: So vertical alignment issue is I have two divs in the last column and I'm trying to get one to stay at top and one to stay at the bottom regardless of how the central column grows. I can work this out by using fixed heights but that's no good in this case.
Here is my code example : JS Fiddle
HTML:
<div class="row" class="property-bundle"><!-- (x) number of these -->
<div class="col-xs-11 wrapper">
<div class="row">
<div class="col-xs-2 pull-left vendor">
<img src="http://placehold.it/100x100" />
</div>
<div class="col-xs-8 properties-list">
<div class="row" class="property-line">
<div class="col-xs-2"><img src="http://placehold.it/80x140" /></div>
<div class="col-xs-10"><p>Flat 1</p></div>
</div>
<div class="row"><hr/></div>
<div class="row" class="property-line">
<div class="col-xs-2"><img src="http://placehold.it/80x140" /></div>
<div class="col-xs-10"><p>Flat 2</p></div>
</div>
<div class="row"><hr/></div>
<div class="row" class="property-line">
<div class="col-xs-2"><img src="http://placehold.it/80x140" /></div>
<div class="col-xs-10"><p>Flat 3</p></div>
</div>
</div>
<div class="col-xs-2 costs"><!-- costs column -->
<div class="row total">
<h3 class="text-right">TOTAL: £1,2M</h3><!--stay at top-->
</div>
<div class="row" class="fees"> <!--stay at bottom-->
<div class="col-xs-12">
<hr/>
<p class="text-right">+ Materials £300K</p>
<p class="text-right">+ Build £100K</p>
</div>
</div>
</div>
</div>
</div>
</div>
CSS:
.wrapper {border: 1px solid black; padding: 10px; margin: 15px;}
.vendor {min-width: 120px;}
.properties-list {background-color: aquamarine}
.costs {vertical-align: top; min-width: 150px; vertical-align: center}
.fees {vertical-align: bottom; }
h3 {font-weight: 400}
h4 {color: green}
.total { margin-right: 0px; }
Hi you can try using flexbox
I just change your html like this:
<div class="col-xs-2 costs">
<!--stay at top-->
<div class="total">
<h3 class="text-right">TOTAL: £1,2M</h3>
</div>
<hr/>
<div class="materials">
<p class="text-right">+ Materials £300K</p>
<p class="text-right">+ Build £100K</p>
</div>
</div>
</div>
Then I add on costs div display:flex;and on total div flex-grow: 1 This flex-grow will push materials on bottom of div.
You just need to add on body, html, row and costs div height:100%
Here is css:
.costs {
vertical-align: center;
display: flex;
flex-direction: column;
height: 100%;
}
.total {
flex-grow: 1;
}
You can see example on this link: https://jsfiddle.net/3L5Lbwhn/9/
Ok I simplified this a bit, but essentially flex did what I needed so many thanks to Edin Puzic for putting me on the right lines! It also allowed me to fix the 1st and last col width and make the middle one dynamic horiontally too.
JsFiddle
<div class="row-flex">
<div class="col-flex-1">
<img src="http://placehold.it/100x100" />
</div>
<div class="col-flex-2">
<div class="row" class="property-line">
<div class="col-xs-2"><img src="http://placehold.it/80x140" /></div>
<div class="col-xs-10">
<p>Flat 1</p>
</div>
</div>
<div class="row">
<hr/>
</div>
<div class="row" class="property-line">
<div class="col-xs-2"><img src="http://placehold.it/80x140" /></div>
<div class="col-xs-10">
<p>Flat 2</p>
</div>
</div>
<div class="row">
<hr/>
</div>
<div class="row" class="property-line">
<div class="col-xs-2"><img src="http://placehold.it/80x140" /></div>
<div class="col-xs-10">
<p>Flat 3</p>
</div>
</div>
</div>
<div class="col-flex-3">
<div class="pos-top">
<div class="row right-text">
TOP right
</div>
</div>
<div class="pos-bottom">
<div class="row right-text">
<p>
BOTTOM right
</p>
</div>
</div>
</div>
</div>
CSS
.row-flex {
height: auto;
display: flex;
flex-flow: row column;
}
.col-flex-1 {
min-width: 200px;
border-left: 1px #ccc solid;
flex: 0 0;
}
.col-flex-2 {
width: 80%;
border-left: 1px #ccc solid;
flex: 1 1;
}
.col-flex-3 {
min-width: 200px;
border-left: 1px #ccc solid;
flex: 0 0;
}
.flex-container {
display: -webkit-flex;
display: flex;
width: 100%;
height: 100%;
background-color: lightgrey;
}
.pos-top {
display: -webkit-flex;
display: flex;
height: 50%;
width: 100%;
-webkit-align-items: flex-start;
align-items: flex-start;
background-color: yellow;
}
.pos-bottom {
display: -webkit-flex;
display: flex;
height: 50%;
width: 100%;
-webkit-align-items: flex-end;
align-items: flex-end;
background-color: green;
}
.right-text {
text-align: right;
width: 100%;
}

bootstraps 3 align bottom with 3 column in row

I've seen this thread but its for 2 column (col-md-6) and I've tried the jsfidlle too for 3 column but column 1st and column 2nd become stack.
Bootstrap 3 Align Text To Bottom of Div
what I want for my project is
.row {
position: relative;
}
.bottom-align-text {
position: absolute;
bottom: 0;
right: 0;
}
<div class="container">
<div class="row">
<div class="bottom-align-text col-sm-4">
<h3>Some Text</h3>
</div>
<div class="col-sm-4">
<img src="//placehold.it/600x300" alt="Logo" class="img-responsive"/>
</div>
<div class="bottom-align-text col-sm-4">
<h3>Some Text</h3>
</div>
</div>
</div>
how to make them both align bottom?
flexbox can do that
.row div {
border: 1px solid red;
}
.flexy {
display: flex;
text-align: center;
}
.flexy .bottom-align-text {
display: flex;
justify-content: center;
align-items: flex-end;
}
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container">
<div class="row flexy">
<div class="bottom-align-text col-sm-4">
<h3>Some Text</h3>
</div>
<div class="col-sm-4">
<img src="//placehold.it/600x300" alt="Logo" class="img-responsive" />
</div>
<div class="bottom-align-text col-sm-4">
<h3>Some Text</h3>
</div>
</div>
</div>
You can wrap column 1st and column 2nd in to a row then we'll have 2 columns structure. See my jsFiddle demo: https://jsfiddle.net/robinhuy/kg1ykfL1/3/

CSS table height of rows not even

I am trying to create a 4x4 array of content using css tables. The cells should be evenly sized. I got a fix to a problem with the cells going out of the parent div. However that broke the height of the cells.
What is wrong here? All the rows should be 25% of the container, with the cells inheriting that. What seems to happen is the first row grows as much as it can, and the 3 remaining ones scale according to the content... Why?
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<style type="text/css">
html,body {
display: block;
height: 100%;
width: 100%;
}
div {
display: block;
}
#container {
background-color: #CCF;
position: absolute;
height: 100%;
width: 100%;
}
.sideBySide {
position: absolute;
float: left;
top: 0px;
height: 100%;
}
#galleria {
background-color:#0C0;
left: 0px;
right: 300px;
width: auto;
}
#tagit {
background-color: #099;
right: 0px;
width: 300px;
}
#table {
position: absolute;
display: table;
height: 100%;
width: 100%;
}
.table-row {
position: relative;
display: table-row;
width: 100%;
height: 25%;
}
.table-cell {
position: relative;
display: table-cell;
height: 100%;
width: 20%;
padding: 20px;
}
.kuva {
position: relative;
width: 100%;
height: 100%;
margin: 10px;
background-color: #999;
}
</style>
</head>
<body>
<div id="container">
<div id="galleria" class="sideBySide">
<div id="table">
<div class="table-row">
<div class="table-cell">
<div class="kuva">
Kuva1
</div>
</div>
<div class="table-cell">
<div class="kuva">
Kuva2
</div>
</div>
<div class="table-cell">
<div class="kuva">
Kuva3
</div>
</div>
<div class="table-cell">
<div class="kuva">
Kuva4
</div>
</div>
</div>
<div class="table-row">
<div class="table-cell">
<div class="kuva">
Kuva1
</div>
</div>
<div class="table-cell">
<div class="kuva">
Kuva2
</div>
</div>
<div class="table-cell">
<div class="kuva">
Kuva3
</div>
</div>
<div class="table-cell">
<div class="kuva">
Kuva4
</div>
</div>
</div>
<div class="table-row">
<div class="table-cell">
<div class="kuva">
text
</div>
</div>
<div class="table-cell">
<div class="kuva">
</div>
</div>
<div class="table-cell">
<div class="kuva">
</div>
</div>
<div class="table-cell">
<div class="kuva">
</div>
</div>
</div>
<div class="table-row">
<div class="table-cell">
<div class="kuva">
test
</div>
</div>
<div class="table-cell">
<div class="kuva">
</div>
</div>
<div class="table-cell">
<div class="kuva">
</div>
</div>
<div class="table-cell">
<div class="kuva">
</div>
</div>
</div>
</div>
</div>
<div id="tagit" class="sideBySide">.</div>
</div>
</body>
</html>
just keeping everything in the flow and dispatching display table/table-row/table-cell to different levels you can get to something like this :
http://codepen.io/anon/pen/pvDwk
To get rid of scrollbar when table can feet window do not forget to add body{margin:0;}

Resources