I have an image on the right side item of a flex container. As you can see in the codepen, there is a gap when expanding the screen (caused by the max-width on the image, which is unavoidable).
However I'm just wanting to move that image to the extreme right-side, so the gap isn't as noticeable.
This needs to be friendly with IE11, and the image needs to be responsive. I would like to avoid using a float on the image if possible (would've thought there is a cleaner way of achieving this using flexbox)?
HTML:
<div class="container">
<div class="image">
<img src="http://www.stevensegallery.com/1000/1400">
</div>
<div class="text">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Doloribus aliquid eius quia expedita illo sequi optio labore assumenda.
</div>
</div>
CSS:
.container {
background-color: red;
display: flex;
flex-direction: row-reverse;
}
.container > .image {
flex: 1 0 0%;
}
.image > img {
display: block;
max-width: 100%;
max-height: 300px;
}
.container > .text {
flex: 2 0 0%;
}
Codepen:
https://codepen.io/neilem/pen/zjpXKZ
You could use vertical-align instead display, then text-align:
.container {
background-color: red;
display: flex;
flex-direction: row-reverse;
}
.container > .image {
flex: 1 0 0%;
text-align:right;/* and here*/
}
.image > img {
vertical-align:top;/* here */
max-width: 100%;
max-height: 300px;
}
.container > .text {
flex: 2 0 0%;
/* and eventually */
margin:auto 0;
}
<div class="container">
<div class="image">
<img src="http://www.stevensegallery.com/1000/1400">
</div>
<div class="text">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Doloribus aliquid eius quia expedita illo sequi optio labore assumenda.
</div>
</div>
Use justify-content property on container and remove flex properties form the flex-child. Your code will look like this. Hope the result is what you desired.
.container {
background-color: red;
display: flex;
flex-direction: row-reverse;
justify-content: space-between;
}
.image > img {
display: block;
max-width: 100%;
max-height: 300px;
}
Related
I am working on a portfolio project and I am creating the projects section.
The width of the projects section is around 350px so only some of the title could be visible but if the text is not able to fit in 350 px it is making the text overflow vertically but I want it to overflow horizontally.
here is my HTML&CSS:
.project-container {
display: grid;
height: 350px;
width: 350px;
background: #c4c4c4;
margin-bottom: 3%;
}
.project-title{
height: 45px;
width: 100%;
background-color: red;
margin: 0;
display: flex;
align-items: center;
justify-content: center;
overflow: auto;
}
<div class="project-container">
<h1 class="project-title">Lorem ipsum dolor sit amet consectetur adipisicing elit. Asperiores dignissimos praesentium dolorem saepe velit at libero a consectetur atque molestias.</h1>
</div>
and here is my result when the text can't fit in 350px:
but I want the overflow to be horizontal
white-space: nowrap;
I think you just want this?
.project-container {
display: grid;
height: 350px;
width: 350px;
background: #c4c4c4;
margin-bottom: 3%;
}
.project-title{
height: 45px;
width: 100%;
background-color: red;
margin: 0;
display: flex;
align-items: center;
justify-content: center;
overflow: auto;
white-space: nowrap;
}
<div class="project-container">
<h1 class="project-title">Lorem ipsum dolor sit amet consectetur adipisicing elit. Asperiores dignissimos praesentium dolorem saepe velit at libero a consectetur atque molestias.</h1>
</div>
You've given your .project-title a width which automatically means the text inside will wrap at the end of the line. If you want it to overflow horizontally instead of vertically, you need to:
Allow space for it to overflow.
Prevent it from wrapping.
This can be achieved by changing .project-title[width] to .project-title[min-width] (meaning the space is at least the width of the container, but may be larger) and setting .project-title[white-space]=nowrap (meaning text is not allowed to break across lines).
.project-container {
display: grid;
height: 350px;
width: 350px;
background: #c4c4c4;
margin-bottom: 3%;
}
.project-title{
height: 45px;
min-width: 100%;
white-space: nowrap;
background-color: red;
margin: 0;
display: flex;
overflow: auto;
}
<div class="project-container">
<h1 class="project-title">Lorem ipsum dolor sit amet consectetur adipisicing elit. Asperiores dignissimos praesentium dolorem saepe velit at libero a consectetur atque molestias.</h1>
</div>
just add white-space: nowrap; to class project-title
I have a simple flex container with 2 items; an image and the other is a small piece of descriptive text.
I'd like the image to grow and be as responsive as possible, but I also want there to be a max-height in place to avoid it growing too much. This causes a gap when the max-height is reached and the screen expands even further in width.
Is there a way to only have the container item fill the image as it grows so there are no gaps, or perhaps align the image to the left or the right side of the screen (self-align didn't appear to work)? I'm not sure what the answer to this is.
.container {
background-color: #FFEEDD;
display: flex;
flex-direction: row-reverse;
}
.container>.image {
flex-grow: 1;
}
.image img {
display: block;
max-width: 100%;
max-height: 300px;
}
.container>.text {
flex-grow: 2;
}
<div class="container">
<div class="image">
<img src="https://www.placecage.com/c/1500/2000">
</div>
<div class="text">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Doloribus aliquid eius.
</div>
</div>
Solution #1
Get rid of
.container > .image {
flex-grow: 1;
}
Solution #2
.image{
text-align:right;
}
Solution #3 (You were trying to achieve this one)
All you needed was to add flex, direction to column and then align items to right by flex-end
.image{
display:flex;
flex-direction:column;
align-items:flex-end;
flex:1;
}
.container {
background-color: #FFEEDD;
display: flex;
flex-direction: row-reverse;
}
.image img {
display: block;
max-width: 100%;
max-height: 300px;
}
.container>.text {
flex-grow: 2;
}
<div class="container">
<div class="image">
<img src="https://www.placecage.com/c/1500/2000">
</div>
<div class="text">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Doloribus aliquid eius.
</div>
</div>
If you want to align the text and image to the sides use justify-content:
.container {
background-color: #FFEEDD;
display: flex;
flex-direction: row-reverse;
justify-content: space-between;
}
.image img {
display: block;
max-width: 100%;
max-height: 300px;
}
codepen
I'd like to use CSS Grid. Something like this I think…
html {
height: 100%;
}
body {
min-height: 100%;
display: grid;
grid-template-rows: auto auto [whatever's left of the vh] auto auto;
position: relative;
}
Set the viewport with display: flex and height: 100vh and add to the last element
flex-grow: 1
.viewportDiv {
display: flex;
flex-direction: column;
height: 100vh;
}
.div1{
background-color: yellow;
height: 100px;
}
.remainingDiv{
background-color: red;
flex-grow: 1;
}
<div class="viewportDiv">
<div class="div1"></div>
<div class="remainingDiv"></div>
</div>
Using CSS Grid you need to wrap the top two elements and the remaining space and then apply display: grid to that.
In other words, your diagram actually was the solution.
The wrapper should have a height of 100vh…
html {
height: 100%;
}
body {
margin: 0;
min-height: 100%;
background: pink;
display: grid;
grid-template-rows: 100vh auto auto;
position: relative;
}
.wrapper {
display: grid;
grid-template-rows: auto auto 1fr;
}
header {
background: green;
padding: .25em;
}
nav {
background: orangered;
padding: .25em;
}
main {
background: rebeccapurple;
}
footer {
background: yellow;
}
.subfooter {
background: blue;
}
<div class="wrapper">
<header>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Ratione magnam placeat quia iusto, quisquam cum temporibus modi, ex dolorem velit fuga! Minima, ex.
</header>
<nav>
Lorem ipsum dolor, sit amet consectetur adipisicing elit.
</nav>
<main></main>
</div>
<footer>Lorem, ipsum.</footer>
<div class="subfooter">Lorem ipsum dolor, sit amet consectetur adipisicing elit. Ex dignissimos ratione maxime officia eum. ea!
</div>
You can do it using flex.
.a {
width: 100%;
height: auto;
}
.remaining {
width: 100%;
flex-grow: 1;
}
.holder {
display: flex;
flex-direction: column;
height: 100%;
}
html,
body {
height: 100%;
}
HTML code:
<div class="holder">
<div class="a">
Content here
</div>
<div class="a">
Content here
</div>
<div class="remaining">
Content here
</div>
</div>
I'm trying to accomplish the following layout, but I'm having trouble with the description box height definition. I'm trying to avoid javascript.
Right now I have both the wrapper and the title bar working as they should, the title and description divs being nested inside the wrapper div:
#wrapper{
position: fixed;
right: 0;
width: calc(100vw - 1.51 * 95vh - 5vh);
top: calc(40px + 2.5vh + 2.5vh);
height: calc(100vh - 40px - 40px);
}
#title{
width: 100%;
height: auto;
top: calc(2.5vh + 40px + 2.5vh + 5vh);
}
What about the description div? Can anyone point me in the right direction?
Thanks!
Flexbox can do that.
.container {
height: 100vh;
display: flex;
flex-direction: column;
}
header {
background: lightblue;
}
.content {
flex: 1;
overflow-y: auto;
background: orange;
}
.spacer {
height: 2000px;
/* for demo purposes */
}
<div class="container">
<header>Lorem ipsum dolor sit amet consectetur adipisicing elit. Quos tenetur magnam labore laboriosam dolores, fugit ipsum quibusdam, aperiam totam itaque soluta debitis cumque provident repudiandae.</header>
<div class="content">
<div class="spacer"></div>
</div>
</div>
What I'm trying to accomplish is a title which fills its available parent div width, but if its copy doesn't fit in the div it should truncate with ellipsis. Additionally it should also have an icon after it, which shouldn't disappear on truncation, but always show after the ellipsis.
Another requirement is that the parent div should have one or more buttons, of not-specific width, that stay on the far right, but if the div is resized it should truncate the long title, allowing the icon to show next to the ellipsis as I described before.
Visually, my desired result looks like this:
Up until now I've achieved the following:
/* Helper styles not relevant to the example */
/* Simple flag object from #csswizardry */
.flag {
display: table;
width: 100%;
}
.flag .flag__section {
display: table-cell;
vertical-align: middle;
}
/* Right float text from bootstrap */
.text-right {
text-align: right !important;
}
/* Colors for better visibility */
.container {
background-color: #55606d;
color: #333;
padding: 20px;
}
.flag__section--a {
background-color: #22d398;
}
.flag__section--b {
background-color: #91c1f8;
}
.fluid-text__icon {
background-color: #fecb52;
}
/* Styles relevant to the example */
.container {
max-width: 700px;
}
.fluid-text {
text-align: left;
}
.fluid-text__inner {
max-width: 100%;
}
.fluid-text__inner,
.fluid-text__copy {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.fluid-text__copy,
.fluid-text__icon {
float: left;
}
.fluid-text__copy {
padding-right: 5px;
}
.fluid-text__icon {
margin-top: 30px;
}
/* I'd like to not set explicit max width here */
.title {
max-width: 600px;
}
<div class='container'>
<div class='flag'>
<div class='flag__section flag__section--a fluid-text'>
<div class='fluid-text__inner'>
<h1 class='fluid-text__copy title'>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Doloremque earum in, voluptas dolorum sit ab modi facere tempora est, sequi molestiae! Commodi vitae sapiente ipsum, nisi facilis impedit aut? Repellendus!
</h1>
<span class='fluid-text__icon'>icon</span>
</div>
</div>
<div class='flag__section flag__section--b text-right'>
<button>ACTION</button>
</div>
</div>
</div>
However, my only concern is that I have to explicitly set .title max-width which is not scalable and I would like to avoid it.
Is there any way to do it without js?
Flexbox can solve this, we just have to expend the ellipsis to the .description div and make a few minor tweaks.
* {
box-sizing: border-box;
}
.parent {
width: 80%;
margin: auto;
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 1em;
padding: .5em;
border: 1px solid grey;
}
.description {
display: flex;
align-items: center;
white-space: nowrap;
overflow: hidden;
}
.text {
flex: 1;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.icon {
flex: 0 0 auto;
background-color: rebeccapurple;
color: white;
padding: .5em;
margin: 0 .25em;
}
.button {
flex: 0 0 auto;
background-color: #ccc;
padding: .5em;
}
<div class="parent">
<div class="description">
<span class="text">Lorem sit amet, consectetur adipisicing elit doloremque earum in, voluptas dolorum sit ab modi facere tempora est, sequi molestiae! Commodi vitae sapiente ipsum, nisi facilis impedit aut? Repellendus!</span>
<span class="icon">I</span>
<span class="icon">I</span>
<span class="icon">I</span>
<span class="icon">I</span>
</div>
<div class="button">
Button
</div>
</div>
<div class="parent">
<div class="description">
<span class="text">Lorem sit amet</span>
<span class="icon">I</span>
<span class="icon">I</span>
</div>
<div class="button">
Button
</div>
</div>
The following uses flex and relies on the known width of the button which seems like the use-case here. The whole contained can have dynamic size, of course. The icon can be any size, too.
.parent {
width: 400px;
background-color: yellow;
display: flex;
justify-content: space-between;
}
.description {
width: calc(100% - 50px);
display: flex;
}
.text {
display: inline-block;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.icon {
display: inline-block;
background-color: tomato;
}
.button {
width: 50px;
background-color: blue;
}
<div class="parent">
<div class="description">
<span class="text">Lorem sit amet, consectetur adipisicing elit doloremque earum in, voluptas dolorum sit ab modi facere tempora est, sequi molestiae! Commodi vitae sapiente ipsum, nisi facilis impedit aut? Repellendus!</span>
<span class="icon">ICON</span>
</div>
<div class="button">
Button
</div>
</div>
<div class="parent">
<div class="description">
<span class="text">Lorem sit amet</span>
<span class="icon">ICON</span>
</div>
<div class="button">
Button
</div>
</div>