automated margin functionality in CSS, not JS

2019-08-05 08:52发布

I have a function written in jQuery that automates the margin-bottom or padding-bottom (conditionally) of a table. Basically it negates the effect of the table cells' borders pushing down the page, keeping the vertical rhythm intact. Instead of using JS to do this, I believe I should be able to with Less and CSS instead.

The condition (if-statement) is based on the number of rows (and thus borders, plus one more) in the table. Since my "magic number" is 24 (24px is the vertical rhythm unit), if the table has (0,11)∪(24,35)∪… borders, the function will make the margin-bottom negative and pull the rest of the page up. However if the table has (12,23)∪(36,47)∪… borders, it will add to the padding-bottom, pushing the rest of the page down to the next vertical rhythm unit. This is all operating under the assumption that each horizontal border in the table is 1px. Extra credit if you can generalize the pattern to work for thicker borders.

Here's my function in jQuery:

/*
Algorithm:
for each table:
take the number of rows (x)
add 12
mod 24
subtract 12
negate.
function notation: g(x) = -(f(x+12)-12) where f(x) = MOD(x,24)
function transformation: MOD(x,24) translated left 12 and down 12, then flipped over the x-axis.
if g(x) <= 0, then margin-bottom that number
else, padding-bottom that number.
*/
$('table').each(function () {
    var n_rows = 0;
    $(this).find('tr').each(function () {
        n_rows++;
    });
    n_rows++; // once more for the last border
    var btm = -(((n_rows + 12) % 24) - 12);
    if (btm <= 0) {$(this).css('margin-bottom',btm);}
    else          {$(this).css('padding-bottom',btm);}
});

Here's what I have so far in my Less:

table {
    counter-reset: nrows;
    tr {
        counter-increment: nrows;
    }
    counter-increment: nrows; // once more for the last border
//  @btm: -(((nrows + 12) % 24) - 12);
//  if (@btm <= 0) {
//      margin-bottom: @btm;
//  } else {
//      padding-bottom: @btm;
//  }
}

Help me out here?

1条回答
老娘就宠你
2楼-- · 2019-08-05 09:28

If i understand your question well, you can use the nth-child pseudo class.

less

.childern(@i){
.margins(@i) when (@i > 0) and (@i < @number/2) {
.margins((@i - 1));
tr:nth-child(@{number}n+@{i})
{
margin-bottom: ~"-@{i}px";
}
}
.margins(@i) when (@i > (@number/2-1)) {
.margins((@i - 1));
tr:nth-child(@{number}n+@{i})
{
padding-bottom: unit(@number - @i,px);
}
}
.margins(@i);
}
table {
.childern(@number);
}
@number: 24;

The above Less code will compile into CSS code as follows:

table tr:nth-child( 24n + 1) {
  margin-bottom: -1px;
}
table tr:nth-child( 24n + 2) {
  margin-bottom: -2px;
}
table tr:nth-child( 24n + 3) {
  margin-bottom: -3px;
}
table tr:nth-child( 24n + 4) {
  margin-bottom: -4px;
}
table tr:nth-child( 24n + 5) {
  margin-bottom: -5px;
}
table tr:nth-child( 24n + 6) {
  margin-bottom: -6px;
}
table tr:nth-child( 24n + 7) {
  margin-bottom: -7px;
}
table tr:nth-child( 24n + 8) {
  margin-bottom: -8px;
}
table tr:nth-child( 24n + 9) {
  margin-bottom: -9px;
}
table tr:nth-child( 24n + 10) {
  margin-bottom: -10px;
}
table tr:nth-child( 24n + 11) {
  margin-bottom: -11px;
}
table tr:nth-child( 24n + 12) {
  padding-bottom: 12px;
}
table tr:nth-child( 24n + 13) {
  padding-bottom: 11px;
}
table tr:nth-child( 24n + 14) {
  padding-bottom: 10px;
}
table tr:nth-child( 24n + 15) {
  padding-bottom: 9px;
}
table tr:nth-child( 24n + 16) {
  padding-bottom: 8px;
}
table tr:nth-child( 24n + 17) {
  padding-bottom: 7px;
}
table tr:nth-child( 24n + 18) {
  padding-bottom: 6px;
}
table tr:nth-child( 24n + 19) {
  padding-bottom: 5px;
}
table tr:nth-child( 24n + 20) {
  padding-bottom: 4px;
}
table tr:nth-child( 24n + 21) {
  padding-bottom: 3px;
}
table tr:nth-child( 24n + 22) {
  padding-bottom: 2px;
}
table tr:nth-child( 24n + 23) {
  padding-bottom: 1px;
}
table tr:nth-child( 24n + 24) {
  padding-bottom: 0px;
}
查看更多
登录 后发表回答