Alex Hall Alex Hall - 5 months ago 15
HTML Question

Make background div same size as content without javascript

I'm trying to achieve a frosted glass effect (translucent, white, blurred background) on a table to make the contents readable while having a nice background. I pretty much have it working below:



if (true /* set to false to test CSS */ ) {
white = document.getElementsByClassName('white')[0];
table = document.getElementsByClassName('table')[0];
white.style.width = table.clientWidth + 'px';
white.style.height = table.clientHeight + 'px';
}

#container {
margin: 20px;
position: relative;
}
.image-background {
background: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/28727/pelican.jpg) no-repeat center center fixed;
background-size: cover;
}
.white {
background-color: white;
/* My attempt at making the div fill the necessary space, not working */
top: 0px;
left: 0px;
right: 0px;
bottom: 0px;
width: 100%;
height: 100%;
}
.blur {
width: 100%;
height: 100%;
-webkit-filter: url(#blur-filter);
-moz-filter: url(#blur-filter);
-o-filter: url(#blur-filter);
-ms-filter: url(#blur-filter);
filter: url(#blur-filter);
opacity: 0.5;
}
#container > div {
position: absolute;
}
table.table > tbody > tr > td {
border: solid 1px black;
}

<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />

<body class="image-background">
<div id="container">
<div class="white">
<div class="blur image-background"></div>
</div>
<div>
<table class="table">
<tr>
<td>1</td>
<td>2</td>
<td>1</td>
<td>2</td>
<td>1</td>
<td>2</td>
<td>1</td>
<td>2</td>
<td>1</td>
<td>2</td>
<td>1</td>
<td>2</td>
<td>1</td>
<td>2</td>
</tr>
<tr>
<td>3</td>
<td>4</td>
<td>3</td>
<td>4</td>
<td>3</td>
<td>4</td>
<td>3</td>
<td>4</td>
<td>3</td>
<td>4</td>
<td>3</td>
<td>4</td>
<td>3</td>
<td>4</td>
</tr>
</table>
</div>
</div>
</body>

<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<defs>
<filter id="blur-filter">
<feGaussianBlur stdDeviation="5"></feGaussianBlur>
</filter>
</defs>
</svg>





However it's a bit fragile as it relies on Javascript to set the dimensions of the background div correctly. For one thing if you zoom in they stop matching and the white spills over. I'm guessing there's a more correct/robust way to do this with CSS, but I'm at the limits of my knowledge and patience here. Other suggestions would also be appreciated.

Answer

The basic technique is to ensure that the table is the only thing that takes up size in the parent (so it can't be absolutely positioned), and that the parent has relative positioning. You can then give the table's siblings absolute positioning and set top/bottom/left/right positioning to 0 to force it to the edges.

Here's the basic proof of concept:

.container {
    position: relative; 
 }

.overlay {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    background-color: rgba(255, 255, 255, 0.5);
}
<div class="container">
  <div class="overlay"></div>
  <div class="table">Content</div>
</div>

And here's a version of your code based on that: http://codepen.io/anon/pen/mEwVGx?editors=1100 I also got rid of the unnecessary table wrapper because it was making things more annoying.