I have a basic html markup, where i am trying to use minimal html wrappers to achieve the design.
The button on the bottom should't align, it should always stay in the bottom.
So my goal is without adding more html wrappers, using flex, force a flex item(button) to drop to the next line. and the block title stay next to the image.
You can see what i mean checking it on mobile breakpoints.
Here are the screenshots with flex-wrap: wrap
And here is with flex-wrap: nowrap
As you see, in first example button is in the bottom as it should be, but block title is dropped to the next line, And in the second example (flex-wrap: wrap) block title is positioned correct, but the button is not in the bottom.
Here is the sandbox link and code example
body {
margin: 0;
padding: 0;
}
.container {
background-color: grey;
overflow: auto;
padding: 20px;
align-items: center;
display: flex;
position: relative;
column-gap: 15px;
flex-wrap: wrap;
/* //try nowrap */
width: 100%;
}
.logo-image {
align-self: flex-start;
}
.headline {
color: white;
}
.text {
color: white;
font-size: 16px;
margin-bottom: 20px;
}
.btn {
display: flex;
width: 100%;
}
button {
align-items: center;
background-color: black;
color: white;
flex: 0 0 100%;
justify-content: center;
margin: 0;
}
<div class="container">
<img src="download.png" width="50px" class="logo-image" alt="img" />
<span class="content">
<h4 class="headline">
Block Title
</h4>
<p class="text">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Sapiente
aliquid sit, cupiditate
</p>
</span>
<div class="btn">
<button>link</button>
</div>
</div>
Any help will be appreciated
You can make your span a block level element and set flex-grow to 1 but set flex-basis to something small, like 50% so it tries to be 50% of the width but will grow to fit the width. It then means when shrinking it will try to stay on the same line.
body {
margin: 0;
padding: 0;
}
.container {
background-color: grey;
overflow: auto;
padding: 20px;
align-items: center;
display: flex;
position: relative;
column-gap: 15px;
flex-wrap: wrap;
width: 100%;
}
/* added this --v */
.content {
display: block;
flex: 1 0 50%;
}
.logo-image {
align-self: flex-start;
}
.headline {
color: white;
}
.text {
color: white;
font-size: 16px;
margin-bottom: 20px;
}
.btn {
display: flex;
width: 100%;
}
button {
align-items: center;
background-color: black;
color: white;
flex: 0 0 90%;
justify-content: center;
margin: 0;
}
<div class="container">
<img src="https://www.fillmurray.com/200/200" width="50px" class="logo-image" alt="img" />
<span class="content">
<h4 class="headline">
Block Title
</h4>
<p class="text">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Sapiente
aliquid sit, cupiditate
</p>
</span>
<div class="btn">
<button>link</button>
</div>
</div>
Related
I have a basic html markup, where i am trying to use minimal html wrappers to achieve the design.
So my goal is without adding more html wrappers, using flex, force 3rd flex item to start from second column like here
1 2
3
Of course, we can achieve adding padding/margin-left for the 3rd element, but I am looking for a solution with css flex and using minimal html markup.
Here is the screenshot what I am trying to achieve
Basically the title and text should start from the same column.
See the code snippet and sandbox link, if you want to test it more
body {
margin: 0;
padding: 0;
}
.container {
background-color: grey;
overflow: auto;
padding: 20px;
align-items: center;
display: flex;
position: relative;
column-gap: 15px;
flex-wrap: wrap;
width: 100%;
}
.content {
display: flex;
flex-wrap: wrap;
}
.logo-image {
align-self: flex-start;
padding-top: 10px;
order: 1;
}
.headline {
color: white;
order: 2;
padding-left: 10px;
}
.text {
color: white;
font-size: 16px;
margin-bottom: 20px;
order: 3;
}
.btn {
display: flex;
width: 100%;
}
button {
align-items: center;
background-color: black;
color: white;
flex: 0 0 90%;
justify-content: center;
margin: 0;
}
<div class="container">
<div class="content">
<h4 class="headline">
Block Title
</h4>
<img src="https://www.fillmurray.com/200/200" width="50px" class="logo-image" alt="img" />
<p class="text">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Sapiente
aliquid sit, cupiditate
</p>
</div>
<div class="btn">
<button>click</button>
</div>
Ideally, you would use CSS Grid for this layout.
Something like this (no changes to the HTML):
.container {
display: flex;
flex-wrap: wrap;
background-color: grey;
column-gap: 15px;
padding: 20px;
}
.content {
display: grid;
grid-template-columns: 50px 1fr;
}
.logo-image {
padding-top: 10px;
order: 1;
}
.headline {
color: white;
order: 2;
padding-left: 10px;
}
.text {
grid-column: 2;
color: white;
font-size: 16px;
margin-bottom: 20px;
order: 3;
}
.btn {
display: flex;
width: 100%;
}
button {
align-items: center;
background-color: black;
color: white;
flex: 0 0 90%;
justify-content: center;
margin: 0;
}
body {
margin: 0;
padding: 0;
}
<div class="container">
<div class="content">
<h4 class="headline">
Block Title
</h4>
<img src="https://www.fillmurray.com/200/200" width="50px" class="logo-image" alt="img" />
<p class="text">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Sapiente aliquid sit, cupiditate
</p>
</div>
<div class="btn">
<button>click</button>
</div>
But if you can only use flex, then you'll have to:
Define a height on the container.
Set the flex-direction to column.
Set flex-wrap to wrap.
Give the first column (containing the image) full height, so it creates a column and forces its siblings into the second column.
(Again, no changes to the HTML.)
.container {
display: flex;
flex-wrap: wrap;
background-color: grey;
column-gap: 15px;
padding: 20px;
height: 200px; /* new (for demo purposes) */
}
.content {
display: flex;
flex-direction: column; /* new */
flex-wrap: wrap;
}
.logo-image {
flex-basis: 100%; /* new */
object-fit: contain; /* new (for proper image rendering) */
object-position: top; /* new (for proper image rendering) */
align-self: flex-start;
padding-top: 10px;
order: 1;
}
.headline {
color: white;
order: 2;
padding-left: 10px;
}
.text {
color: white;
font-size: 16px;
margin-bottom: 20px;
order: 3;
}
.btn {
display: flex;
width: 100%;
}
button {
align-items: center;
background-color: black;
color: white;
flex: 0 0 90%;
justify-content: center;
margin: 0;
}
body {
margin: 0;
padding: 0;
}
<div class="container">
<div class="content">
<h4 class="headline">Block Title</h4>
<img src="https://www.fillmurray.com/200/200" width="50px" class="logo-image" alt="img" />
<p class="text">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Sapiente
aliquid sit, cupiditate
</p>
</div>
<div class="btn">
<button>click</button>
</div>
If you can't define a height on the container, then use the Grid version.
/* added this --v */
.content {
display: grid; /* ----- new ------- */
grid-template-columns: auto 1fr; /* ----- new ------- */
grid-template-rows: 1fr 1fr; /* ----- new ------- */
column-gap: 15px; /* ----- new ------- */
}
<body>
<div class="container">
<div class="content">
<!-- bring the img element above of h4 because we want it to be in the first item of our grid layout -->
<img src="download.png" width="50px" class="logo-image" alt="img" />
<h4 class="headline">
Block Title
</h4>
<p class="text">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Sapiente
aliquid sit, cupiditate
</p>
</div>
<div class="btn">
<button>link</button>
</div>
</div>
</body>
1.you need to use a two-dimensional layout which is grid (instead of flexbox)
2.you need to use grid for the element that has .content class
.content { display: grid; grid-template-columns: auto 1fr; grid-template-rows: 1fr 1fr; column-gap: 15px; } <br>
3.you need to define the p element that has .text class to start from the 2nd column and ends in the 3rd column with this code: grid-column: 2/3;
and here is the result : https://codesandbox.io/s/brave-zhukovsky-7g12bj?file=/style.css:566-583
I don't know where that box thingy comes from under the (-) button. It stretches when the single-card div becomes bigger. When I take out rating div from the single-card div, there is no box thingy under the (-) button. Can anyone please help? Thank you.
I don't know where that box thingy comes from under the (-) button. It stretches when the single-card div becomes bigger. When I take out rating div from the single-card div, there is no box thingy under the (-) button. Can anyone please help? Thank you.
*,*::before, *::after {
margin: 0;
padding: 0;
box-sizing: border-box;
--violet: #8F00FF;
--usernamecolor: rgb(43, 72, 83);
}
.single-card {
margin-top: 60px;
display: flex;
justify-content: center;
background-color: white;
}
.rating {
border-radius: 8px;
width: 35px;
background-color: #f0f0f0;
display: flex;
flex-direction: column;
align-items: center;
box-shadow: -5px 0px 8px rgba(172, 169, 169, 0.1);
overflow: hidden;
margin-right: 15px;
}
button {
border: none;
height: 30px;
border-radius: 8px;
align-items: center;
color: var(--violet);
font-weight: bold;
cursor: pointer;
opacity: 0.7;
}
button:hover {
color: purple;
opacity: 1;
}
.rating span {
height: 30px;
display: flex;
justify-content: center;
align-items: center;
color: var(--violet);
font-weight: bold;
}
.wrapper {
width: 800px;
padding: 8px;
}
.top {
display: flex;
align-content: center;
justify-content: space-between;
}
.top .top-left {
display: flex;
}
.top img {
width: 40px;
border-radius: 100%;
margin-right: 15px;
border: 1px solid blue;
}
.top .username {
padding-top: 5px;
margin-bottom: 1px;
margin-right: 10px;
font-weight: bold;
color: var(--usernamecolor);
}
.top .date {
padding-top: 5px;
margin-bottom: 1px;
opacity: 0.8;
}
.top button {
background-color: white;
display: flex;
align-items: center;
}
<div class="single-card">
<div class="rating">
<button>+</button>
<span>12</span>
<button>-</button>
</div>
<div class="wrapper">
<div class="top">
<div class="top-left">
<div><img src="photo.jpg" alt=""></div>
<p class="username">amyrobson</p>
<p class="date">1 month ago</p>
</div>
<button><box-icon name='reply'></box-icon>Reply</button>
</div>
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Vero at ut facere. Quae eos soluta nesciunt perspiciatis neque a ipsa omnis eligendi nemo quidem similique, autem minima? Facilis, voluptatibus voluptatum.</p>
</div>
</div>
The - display: flex on .single-card is the cause, in the flexbox container if some items are taller than others, all items will stretch along the cross axis to fill its full size.
add to the container(.single-card): align-items: center / start / end (choose one option as it feet’s your design)
you can read more about it - https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox
I can make the basic Holy Grail layout, but once it comes to putting boxes inside boxes, things fall apart. I have looked at code for comparison, but this specific layout doesn't seem very common.
What I want to do is have 4 flexboxes inside the main content of the webpage. Above the boxes is a header, maybe a paragraph underneath that. Under the flexboxes are a description for each, that is centered and aligned with the flexbox. The flexboxes will hold a picture, but that is not important right now.
https://codepen.io/ct2k/pen/mdqdpzw
}
html, body {
margin: 0;
padding: 0;
font-family: sans-serif;
font-size: 1.1em;
text-align: center;
color: #FFF;
}
.holy-grail header,
.holy-grail footer,
.hg-sidebar,
.holy-grail-content {
padding: 20px;
}
.holy-grail header,
.holy-grail footer {
background: #0c31aa;
}
.hg-sidebar {
background: #b7d3ec;
}
.holy-grail-content {
color: #777;
}
.holy-grail {
min-height: 100vh;
}
.holy-grail,
.holy-grail-body {
display: flex;
flex: 1 1 auto;
flex-direction: column;
}
.holy-grail-content {
flex: 1 1 auto;
display: flex;
justify-content: center;
}
#media (min-width: 768px) {
.holy-grail-sidebar-1 {
order: -1;
}
.holy-grail-body {
flex-direction: row;
}
.hg-sidebar {
flex: 0 0 260px;
}
.block {
border: solid;
border-color: cornflowerblue;
width: 200px;
height: 200px;
font-size: 48px;
text-align: center;
}
.mc {
display: flex;
justify-content: center;
align-items: center;
}
You can insert those divs of the card inside other major div
I try to solve it quickly using another div to store
the header for the card
paragraph
card
description of card
html, body {
margin: 0;
padding: 0;
font-family: sans-serif;
font-size: 1.1em;
text-align: center;
color: #FFF;}
html, body {
margin: 0;
padding: 0;
font-family: sans-serif;
font-size: 1.1em;
text-align: center;
color: #FFF;
}
.holy-grail header,
.holy-grail footer,
.hg-sidebar,
.holy-grail-content {
padding: 20px;
}
.holy-grail header,
.holy-grail footer {
background: #0c31aa;
}
.hg-sidebar {
background: #b7d3ec;
}
.holy-grail-content {
color: #777;
flex: 1 1 auto;
display: flex;
justify-content: center;
/*Add this line*/
flex-direction: column;
}
.holy-grail {
min-height: 100vh;
}
.holy-grail,
.holy-grail-body {
display: flex;
flex: 1 1 auto;
flex-direction: column;
}
#media (min-width: 768px) {
.holy-grail-sidebar-1 {
order: -1;
}
.holy-grail-body {
flex-direction: row;
}
.hg-sidebar {
flex: 0 0 260px;
}
.block {
border: solid;
border-color: cornflowerblue;
width: 200px;
height: 200px;
font-size: 48px;
text-align: center;
}
.mc {
display: flex;
justify-content: center;
align-items: center;
}
.card-with-header-and-desc-container {
text-align: center;
width: 200px;
/*height: 200px;*/
}
.card-with-header-and-desc-container__header {
font-weight: 700;
font-size: 1.5rem
}
.card-with-header-and-desc-container__sub {
font-weight: 500;
font-size: 1.1rem
}
.extra-text{
margin: 0 10px;
}
}
.holy-grail header,
.holy-grail footer,
.hg-sidebar,
.holy-grail-content {
padding: 20px;
}
.holy-grail header,
.holy-grail footer {
background: #0c31aa;
}
.hg-sidebar {
background: #b7d3ec;
}
.holy-grail-content {
color: #777;
}
.holy-grail {
min-height: 100vh;
}
.holy-grail,
.holy-grail-body {
display: flex;
flex: 1 1 auto;
flex-direction: column;
}
.holy-grail-content {
flex: 1 1 auto;
display: flex;
justify-content: center;
}
#media (min-width: 768px) {
.holy-grail-sidebar-1 {
order: -1;
}
.holy-grail-body {
flex-direction: row;
}
.hg-sidebar {
flex: 0 0 260px;
}
.block {
border: solid;
border-color: cornflowerblue;
width: 200px;
height: 200px;
font-size: 48px;
text-align: center;
}
.mc {
display: flex;
justify-content: center;
align-items: center;
}
<!DOCTYPE html>
<html lang="en">
<body class="holy-grail">
<!--<body class="holy-grail">-->
<header>
<p>Header</p>
</header>
<div class="holy-grail-body">
<section class="holy-grail-content">
<h1>Main content</h1>
<div class="mc">
<div class="card-with-header-and-desc-container">
<p class="card-with-header-and-desc-container__header">Some header</p>
<p class="card-with-header-and-desc-container__sub">maybe a paragraph</p>
<div class="block block1">1
</div>
<p>Description of each card Lorem ipsum dolor sit amet consectetur adipisicing elit. </p>
</div>
<p class="extra-text">Whats</p>
<div class="card-with-header-and-desc-container">
<p class="card-with-header-and-desc-container__header">Some header</p>
<p class="card-with-header-and-desc-container__sub">maybe a paragraph</p>
<div class="block block2">2
</div>
<p>Description of each card Lorem ipsum dolor sit amet consectetur adipisicing elit. </p>
</div>
<p class="extra-text">In</p>
<div class="card-with-header-and-desc-container">
<p class="card-with-header-and-desc-container__header">Some header</p>
<p class="card-with-header-and-desc-container__sub">maybe a paragraph</p>
<div class="block block3">3
</div>
<p>Description of each card Lorem ipsum dolor sit amet consectetur adipisicing elit. </p>
</div>
<p class="extra-text">The</p>
<div class="card-with-header-and-desc-container">
<p class="card-with-header-and-desc-container__header">Some header</p>
<p class="card-with-header-and-desc-container__sub">maybe a paragraph</p>
<div class="block block4">4
</div>
<p>Description of each card Lorem ipsum dolor sit amet consectetur adipisicing elit. </p>
</div>
<p class="extra-text">Box?</p>
</div>
</section>
<div class="holy-grail-sidebar-1 hg-sidebar">
<p>Sidebar 1</p>
</div>
<div class="holy-grail-sidebar-2 hg-sidebar">
<p>Sidebar 2</p>
</div>
</div>
<footer>
<p>Footer</p>
</footer>
</body>
</html>
Example applied
if this does not solve your problem consider adding some images showing what your expected design is.
I'd normally just use line-height for vertical centering, but on this occasion the layout I'm working to is a little trickier.
I've put together this jsfiddle to show where I'm at so far. All the CSS hacks suggest using table-cell trickery for this but I can only get it to work if the wrapper has an absolute height, so for me this text isn't vertically centered:
<div class="wrap">
<a href="#">
<img src="http://www.thekrausemouse.com/wp-content/uploads/2016/03/sample-1.jpg" />
<span class="text"><span>Text that might span multiple lines</span></span>
</a>
</div>
https://jsfiddle.net/fdtbvmcw/
What I basically need is for the text, regardless of how many lines it spans, to sit in the middle of the image. The image can't be a background-image and I can't attach fixed widths or heights to the wrapper.
The wrapper is simulating a responsive column within a bigger page template and I need the image to retain full width of that column you see. Other HTML can be added within the column if need be.
Thoughts?
Flexbox can do that...
.wrap {
height: auto;
position: relative;
width: 50%;
}
.wrap a img {
height: auto;
width: 100%;
}
.wrap a span.text {
height: 100%;
left: 0;
position: absolute;
text-align: center;
top: 0;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.wrap a span.text span {
color: #fff;
font-size: 20px;
font-weight: bold;
line-height: 1.25
}
<div class="wrap">
<a href="#">
<img src="http://www.thekrausemouse.com/wp-content/uploads/2016/03/sample-1.jpg" />
<span class="text"><span>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Id praesentium nihil iure amet dolore nulla totam modi </span></span>
</a>
</div>
I think is better use translateY, it works in more devices
//CSS
.wrap {
height: auto;
position: relative;
width: 50%;
}
.wrap a img {
height: auto;
width: 100%;
}
.wrap span {
color: #fff;
font-size: 26px;
font-weight: bold;
line-height: 30px;
vertical-align: middle;
top: 50%;
transform: translateY(-50%);
display:block;
position:absolute;
text-align:center;
}
//HTML
<div class="wrap">
<a href="#">
<img src="http://www.thekrausemouse.com/wp-content/uploads/2016/03/sample-1.jpg" />
<span>Text that might span multiple lines</span>
</a>
</div>
https://jsfiddle.net/MAXXALANDER/fdtbvmcw/2/
I would also use flex for your solution.
.wrap a .text {
height: 100%;
left: 0;
position: absolute;
text-align: center;
top:0;
display: flex;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
justify-content: center;
align-items: center;
}
I am trying to design a landing page where different sections have different background-colors. The first section container (brown background) is a Flexbox to position the child elements. Below the first section comes another container (blue background) that also spans the whole width of the page.
Problem: There is some whitespace between the two containers, that I can't remove.
body {
margin: 0;
}
.about-container {
width: 100%;
height: 490px;
display: flex;
justify-content: space-around;
align-items: center;
flex-wrap: wrap;
background: #605B56;
}
#title {
font-size: 28px;
font-weight: 200;
color: #8EB8E5;
}
.pic {
width: 200px;
height: 200px;
border-radius: 50%;
background: #8EB8E5;
}
p {
text-align: right;
color: $white;
}
h3 {
text-align: center;
}
.section-container {
background: #8EB8E5;
}
<div class="about-container">
<div class="about-text">
<h3 id="title">Title</h3>
<p> Lorem ipsum dolor sit amet</p>
</div>
<div class="pic"></div>
</div>
<div class="section-container">
<h3>
Section Title
</h3>
Some text for the next section
</div>
JSFiddle: https://jsfiddle.net/z4oecan1/
Your <h3> elements have a default margin; remove it. use padding on the <h3> instead if you need to push it down.
body {
margin: 0;
}
.about-container {
width: 100%;
height: 490px;
display: flex;
justify-content: space-around;
align-items: center;
flex-wrap: wrap;
background: #605B56;
}
#title {
font-size: 28px;
font-weight: 200;
color: #8EB8E5;
}
.pic {
width: 200px;
height: 200px;
border-radius: 50%;
background: #8EB8E5;
}
p {
text-align: right;
color: $white;
}
h3 {
text-align: center;
margin: 0;
}
.section-container {
background: #8EB8E5;
}
<div class="about-container">
<div class="about-text">
<h3 id="title">Title</h3>
<p> Lorem ipsum dolor sit amet</p>
</div>
<div class="pic"></div>
</div>
<div class="section-container">
<h3>
Section Title
</h3>
Some text for the next section
</div>
Another option is to leave the margins as-is and add overflow:auto to the section-container div to fix the collapsed margins.
body {
margin: 0;
}
.about-container {
width: 100%;
height: 490px;
display: flex;
justify-content: space-around;
align-items: center;
flex-wrap: wrap;
background: #605B56;
}
#title {
font-size: 28px;
font-weight: 200;
color: #8EB8E5;
}
.pic {
width: 200px;
height: 200px;
border-radius: 50%;
background: #8EB8E5;
}
p {
text-align: right;
color: $white;
}
h3 {
text-align: center;
}
.section-container {
background: #8EB8E5;
overflow:auto;
}
<div class="about-container">
<div class="about-text">
<h3 id="title">Title</h3>
<p> Lorem ipsum dolor sit amet</p>
</div>
<div class="pic"></div>
</div>
<div class="section-container">
<h3>
Section Title
</h3>
Some text for the next section
</div>
It's due to the default margin-top of the h3 in the second section, which exceeds its container (collapsing margins....)
To avoid that, set margin-top: 0 for that h3, and to recreate the space above it, add a padding-top to it.
https://jsfiddle.net/031p3m04/1/