HTML responsive grid, with line under intermediate rows - html

I need to have a layout presenting a grid of floating divs with an horizontal line under intermediate rows. There shouldn't be a line under the last row, and of course if there is only one row of elements, no line under it..
The problem is that size of the page is variable, my elements always have the same size, ergo there the number of columns is relative.
I know how to do this when i have the same number of columns, but not the variable ones.
This is a sketch for clarity:
I am using bootstrap if that makes a difference..
Any suggestions, please?

This might be a solution (if you don't have a background image):
Add the line under the units inside the flex container, and add an extra white line to overwrite the border of the bottom elements.
The divs in this example are just containers. Any padding and margin should be applied to elements inside them. I've made the units grey, and the bottom line light pink to show them, but in reality they should be transparent and white respectively.
.container {
display: flex;
flex-flow: row wrap;
overflow: hidden;
position: relative;
}
.container div {
display: inline-block;
background-color: #eee;
width: 140px;
height: 120px;
padding: 10px;
border-bottom: 3px solid red;
}
.container::after {
position: absolute;
content: "";
display: block;
height: 3px;
width: 100%;
left: 0;
bottom: 0;
background-color: #FFF; /* Make this white. */
}
<div class="container">
<div>A</div><div>A</div><div>A</div><div>A</div><div>A</div><div>A</div><div>A</div><div>A</div><div>A</div><div>A</div><div>A</div><div>A</div>
</div>

You could try this, where the "black" background-color is equal to your body/container background colour.
https://jsfiddle.net/e125u41f/1/

Related

How to bring in the margin in the calculation of the width of an image?

The following code generates a masonry layout:
<ngx-masonry class="masonry" [options]="myOptions">
<div ngxMasonryItem class="masonryItem" *ngFor="let post of posts;index as idx" (click)="showPostDetail(post)" >
<div class="crop">{{post.description}}</div>
<img [src]="imgConstructor(post.img)">
</div>
</ngx-masonry>
Now the css code:
.masonryItem {
padding: 7px;
margin-top: 5px;
background-color: darkgoldenrod;
border: 0.4px solid black;
width: 20%;
}
.masonryItem img {
object-fit: cover;
max-width: 100%;
min-width: 100%;
}
So five images are displayed in a row since the width of each item is 20%. But now I want to include a margin-property in my css code in the masonryItem class
.masonryItem {
margin: 1rem
}
But then there would be only 4 images in a row and some space on the right on the masonry-grid. So how to bring in the margin-property in my width-calculation such that five images are displayed in each row?
MY SOLUTION:
Add a border property with 1rem:
.masonryItem{
border: 1rem solid white;
}
It looks like margin 1rem if the background-color and border-color is the same. Then the amount of images per row is identically.
If you are using this library: https://github.com/wynfred/ngx-masonry, there is a gutter property that should permit to change the distance between items.
For this kind of display, you should probably use a "display: flex" with a "gap" property for the spaces between element.

Split two divs with diagonal line, scaling to content

I've got a mockup for a website which has a hero section consisting of two sections, split diagonally at the same angle. The two sections have content and need to scale to fit the content.
I have tried the method described here: two divs split with diagonal line - CSS
but it doesn't work well with content; adding text to the div just extends the rectangle not the triangle. How do I get the boxes to scale with the content?
I would post a comment but I don't have the reputation :/
EDIT: by scaling to content, I mean that the if I add content to one of the divs, the div should be able to fit all of the content inside of it. Both of the divs would need to be the same height. Apologies for any confusion :)
The question is not so clear as to :
scaling to content
I suppose it means that it should keep the same aspect after window resize (??).
// Create a flex container
.hero {
display: flex;
height: 500px;
width: 100%;
flex-flow: row nowrap; // make the two divs side by side
font-size: 2em;
color: white;
font-family: sans-serif;
position: relative;
}
// apply basic styles to the divs
.hero div{
display: flex;
position: relative;
background-color: tomato;
width: 50%;
padding: 50px;
}
// + 100px for :after and :before to fit
// + 10px for the space we really want to see between diagonal
.hero div:first-child{
margin-right: 110px;
}
.hero_1:after, .hero_2:before{
content:'';
position: absolute;
top: 0;
width: 0;
height: 0;
}
// Add a triangle at the end and starts of both divs to simulate diagonal
.hero_1:after {
left: 100%;
border-top: 500px solid tomato;
border-right: 100px solid transparent;
}
.hero_2:before {
right: 100%;
border-bottom: 500px solid tomato;
border-left: 100px solid transparent;
}
Please have a look to this codepen. The split is made with a diagonal line, and it fits to window resizes.
If it's not the desired effect, please edit the question to be more explicit about "scaling to content" I'll be happy to help.

Displaying three elements inside a <div> in a same line

This is the html code:
<div class="produto_title">
<h2 th:text="${produto.name}"></h2>
Baixar
Comprar <span th:text="${produto.preco}"></span>
</div>
Could anyone give me a hint how to place the three items inside .produto_title in a same line (h2 floating at left and the two a floating at right).
Also, h2 has a border around item and the a is displayed like a button; I want add a line behind crossing all the "line" formed by this three elements, like this:
jsfiddle: https://jsfiddle.net/klebermo/sf7a6fnj/5/
ps.: also, how let the content of tag <span> inside the button, like the text?
An hr is a block element that's essentially just a line with a border.
I'd recommend sticking one of those at the top of the container and giving it a negative margin that vertically centers it in the parent. position: absolute is more trouble than it's worth.
https://jsfiddle.net/JackHasaKeyboard/0juqg4j7/
As for aligning the elements to the left and the right, I'll let you figure that out. There's many ways to accomplish it, the simplest way being with float.
I would look at twitter's bootstrap, specifically the row and col components.
You could do
<div class="row">
<div class="col-md-4">
// something here
</div>
<div class="col-md-4">
// something here
</div>
<div class="col-md-4">
// something here
</div>
</div>
This will all be displayed on the same line, splitting the row into equal thirds
btns{
height: auto; //Fix the span not being in the element
margin-top: 20px; //line everything up with the top of the heading element.
}
As for the line you can make a div and give it a absolute position (remember to give parent a relative position) and then position it accordingly.
.parent{
position: relative;
width: 100%;
}
.line{
height: 4px;
background-color: #000;
position: absolute;
z-index: -1;
top: 50%;
width: 100%;
}
This is a very bare-bones answer but it will be a start for you to go off.
For the first question, you can do that easily by manipulating margin or vertical-align properties. For example, if you put margin: 30px 5px; on your btn elements, it would be on the same line-ish.
Secondly, the <span> problem: if you set fixed width: 60px; of element (in your case .btn_comprar), text would either overflow from button to the right or bottom. Try setting width: 90px; or more on button elements, or height: auto; if you need it to be fixed.
Updated fiddle
First of all, you can't set a fixed width on a button if you want the text to not wrap. I recommend leaving the buttons at a width: auto and using padding to control the spacing around the text. I'd also bundle the styles for both button selectors, as they're exactly the same
Secondly, the only way (I know of) to get items to vertically align while they're float: right is by manually pushing them down, so I recommend making your buttons position: relative and setting a top: 25px;
/* Bundled both buttons together as they share the same styles */
.btn_free,
.btn_comprar {
float: right;
/* width: 60px; Removing this to allow the text to set the button width */
/* height: 20px; Removing this to let the line-height set the button height */
background: silver;
border-radius: 5px;
padding: 1px 15px;
box-shadow: 1px 1px 1px #000;
/* display: block; Removing this as floats are automatically display: block; */
/* text-align: center; Removing this since the text is already setting width */
background-image: linear-gradient(to bottom, #f4f5f5, #dfdddd);
font-family: arial;
font-size: 12px;
line-height:20px;
position: relative; /* Pushing buttons down a bit */
top: 25px;
margin: 0 10px; /* Spacing buttons out */
}
.btn_free:hover,
.btn_comprar:hover{
background-image: linear-gradient(to bottom, #c3e3fa, #a5defb);
}
Thirdly, remember to use a clearfix so the .produto_title container maintains height!
.produto_title:after {
content: "";
display: table;
clear: both;
}
Lastly, rather than using another div to make the line, I'd use the :before psuedo-element on .produto-title (can't use :after if you're also doing a clearfix).
.produto_title:before {
content: '';
height: 1px;
background: #000;
width: 100%;
position: absolute;
left: 0;
top: 50%;
display: block;
}
Here's a working demo:
https://jsfiddle.net/zcqLbg4h/1/

Move divs vertically within a larger div

I am making an animation that involves a set of four divs inside one larger div. The four divs are too large to all fit in the one div at once, so I want to be able to specify the position at which the larger div should start. For example, here I have four boxes inside the div. From top to bottom, the boxes are green, purple, pink, and blue (you can't see the blue in the current jsfiddle because it is cut off). I would like the BOTTOM of the larger fulldisplay div to align with the MIDDLE of the blue box, and everything else to fit above hat until it is cut off at the top of the div. Eventually I am going to be implementing a custom-made scroll button (as I don't want it to look like the overflow:scroll one) but for now I am just trying to get CSS to display the inner divs the way I want.
JS FIDDLE: http://jsfiddle.net/o33gw35w/
CSS:
body {padding: 0; margin: 0; height: 100%; overflow: hidden; font-family: Helvetica;}
.nameblock {
height:10%;
width: 30%;
position: absolute;
background-color: yellow;
}
.fulldisplay {
height:90%;
width: 30%;
position: absolute;
overflow: hidden ;
}
.spacer1 {
height:40%;
position: relative;
background-color: green;
}
.spacer2{
height:40%;
position: relative;
background-color: purple;
}
.spacer3 {
height:40%;
position: relative;
background-color: pink;
}
.spacer4{
height:40%;
position: relative;
background-color: blue;
}
HTML:
<div class="nameblock"></div><br/>
<div class="fulldisplay">
<div class="spacer1">
</div>
<div class="spacer2">
</div>
<div class="spacer3"></div>
<div class="spacer4"></div>
</div>
</body>
Apologize if I got the question wrong as I am not quite sure what you are trying to do, but if you want to have a way of ordering s dynamically, you could use css flexbox to do so. You might need to tweak the classes to have correct width and height (eg. width: 100%; height: 150px;) and define flex container as similar to below snippet.
.fullconversation {
padding: 0;
margin: 0;
list-style: none;
width: 30%;
display: flex;
flex-direction: row;
-webkit-flex-flow: row wrap;
justify-content: space-around;
}
and then
.spacer4{
width: 100%;
height: 150px;
position: relative;
background-color: blue;
order: -1;
}
For more information about flexbox, please refer to the urls below or feel free to ask any questions regarding flexbox or css. Hope this helps.
https://css-tricks.com/almanac/properties/o/order/
https://css-tricks.com/snippets/css/a-guide-to-flexbox/
***********Updated************
If you change the height of spacer1 to be 10%, then you will see the blue box visible at the bottom. Note that the value 10% is just an example, as long as the total size of the heights of inner s dose not take up more than 100%, the blue box will be visible.
.spacer1 {
height:10%;
position: relative;
background-color: green;
}
Also, if you want to see all divs regardless of the size, you could just set overflow to other than hidden.

Equal height columns with absolutely positioned elements

I have an unordered list that has a bit of content and a button. The columns (LIs) will not always be the same height, but I want the button to always be at the bottom. I'm using the display: table / display: table-cell trick to keep the LIs the same height, however I can't get the button to align correctly. I want the button at the bottom, but I also want it to behave like the content does. Meaning I want it centered and to change it's width as the browser is resized.
Here's a fiddle that demonstrates the issue.
http://jsfiddle.net/mattymess/BBuqY/
This is a snippet of code showing how I'm doing the equal height...
.rewards .rewards-chooser {
margin: 0;
border-top: 2px solid #f4f4f4;
border-bottom: 2px solid #f4f4f4;
display: table;
width: 100%;
position: relative;
}
.rewards .reward {
width: 25%;
border-left: 2px solid #f4f4f4;
list-style: none;
display: table-cell;
}
Change position: absolute; to position: relative; in .rewards .reward .redeem class like this:
.rewards .reward .redeem {
position: relative;
bottom: 0;
box-sizing: border-box;
}
Just to knowledge: Your button is relative to something (your container), and not absolute.
To set the buttons in the same line, you should to define a height for the container scope. Something like this:
.reward-description {
height: 200px;
}
I made a clean example for you. To see, click here (jsFiddle).