I have tried adapting this post and its alistapart links. But I can't get my three blocks in a container to act responsively and maintain their aspect ratio
<div class="hpGridTopRow">
<span class="hpBox lightBlue one">
<p class="hbBoxesp">New to Restore</p>
</span>
<span class="hpBox green two">
<p class="hbBoxesp">Events</p>
</span>
<span class="hpBox midBlue three">
<p class="hbBoxesp">Talks</p>
</span>
</div>
I need them to arrange themselves to the borders of the hpGridTopRow div so I am using flex - and its working well.
However, the layout has to be responsive - the aspect ratio of the containers needs to stay fixed as their widths change.
Here's the css
.hpGridTopRow,
.hpGridBottomRow {
display: -webkit-flex;
display: flex;
-webkit-justify-content: space-between;
justify-content: space-between;
position: relative;
padding-bottom: 20%;
height: 0;
overflow:hidden;
background:yellow;
}
.hpBox {
width:24.18803418803419%;
text-align:center;
height:264px;
height:100%;
}
.hpBox.one {
width:49.4017094017094%;
}
.lightBlue {
background:#15b2d2;
}
.green {
background:#8cc63f;
}
.midBlue {
background:#6a8aa8;
}
.hbBoxesp {
color:#fff;
margin-top:40px;
}
I have created a jsfiddle - as you can the container background shows, but not the actual boxes and said container is behaving responsively.
How can I get the spans to behave properly?
I've removed those extra colors and simplified the percentages to simplify the code.
The idea is that I've added position: relative; to the parent and position: absolute; to the children. This ensures that the children positions are bounded to the parent.
I've also added top: 0; bottom: 0; to the children, to make the children span spans the height as the parent div.
Then you have to place the spans in the correct places by using left and right positioning.
.hpGridTopRow {
display: -webkit-flex;
display: flex;
-webkit-justify-content: space-between;
justify-content: space-between;
position: relative;
padding-bottom: 20%;
height: 0;
overflow: hidden;
background: yellow;
position: relative;
}
.hpBox {
width: 25%;
text-align: center;
position: absolute;
top: 0;
bottom: 0;
}
.hpBox.one {
width: 50%;
}
.hpBox.two {
left: 50%;
}
.hpBox.three {
right: 0;
}
.lightBlue {
background: #15b2d2;
}
.green {
background: #8cc63f;
}
.midBlue {
background: #6a8aa8;
}
.hbBoxesp {
color: #fff;
margin-top: 40px;
}
<div class="hpGridTopRow">
<span class="hpBox lightBlue one">
<p class="hbBoxesp">New to Restore</p>
</span>
<span class="hpBox green two">
<p class="hbBoxesp">Events</p>
</span>
<span class="hpBox midBlue three">
<p class="hbBoxesp">Talks</p>
</span>
</div>
Related
I need to fade out a long text when some buttons start:
I'm using flex (and need to use it as it's part of a bigger template and I'm not sure about the side effects of changing the display), so passing everything to display: absolute is not an option, so using position: absolute is not easy.
.kt-portlet__head {
display: flex;
justify-content: space-between;
position: relative;
}
.kt-portlet__head-label {
display: flex;
align-items: center;
}
.kt-portlet__head-toolbar {
display: flex;
align-items: center;
align-content: flex-end;
}
<div class="kt-portlet__head">
<div class="kt-portlet__head-label">
<h3>
This is a really long campaign name that should faaaaaaaade out when it reaches the Statistics button
</h3>
</div>
<div class="kt-portlet__head-toolbar">
<div>
<div>
<a href="#" class="btn btn-brand">
<span>This is a button - text fade out from there</span>
</a>
</div>
</div>
</div>
</div>
Using a CSS mask, you can actually make this even simpler.
It's a CSS feature that has 98% support globally, though most browsers require a -webkit prefix still.
.wrap {
display: flex;
}
p {
-webkit-mask-image: linear-gradient(to left, rgb(0 0 0 / 0), black);
mask-image: linear-gradient(to left, rgb(0 0 0 / 0), black);
}
<div class="wrap">
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Lorem ipsum dolor sit, amet consectetur adipisicing elit.</p>
<button>This is a button - text fade out from there</button>
</div>
First we'll set the parent div's display to flex and max-width to 100% or whatever size you want. next set the flex-wrap to nowrap so the items don't get sent to another row.
no need to determine how much width the button's gonna take, you can set its width to auto so that it'll take up as much space as needed or you can set a max-width like me, so that no matter what it'll only take up 30% of the width.
next we'll set flex:1 for the .kt-portlet__head-label div, so that no matter how wide the button or the parent div is, it'll always take up the remaining space from the start of the parent div until the start of the button block, and also set min-width: 0 so that it won't override the width and max-width properties and overflow out of its container, next we'll set it's position to relative and we'll add a before tag with position:absolute that starts from the right side of the div, and has a linear-gradient background for the fade effect.
At last we'll set the h3 tag's white-space: nowrap so the text will stay in a single line and overflow:hidden to clip the text's overflow.
.kt-portlet__head {
display: flex;
justify-content: space-between;
position: relative;
align-items: center;
max-width: 100%;
width: 100%;
flex-wrap: nowrap;
}
.kt-portlet__head-toolbar {
width: auto;
max-width:30%;
}
.kt-portlet__head-label {
flex: 1;
min-width: 0;
position: relative;
margin-right: 3px;
}
.kt-portlet__head-label h3 {
overflow: hidden;
white-space: nowrap;
overflow: hidden;
max-width: 100%;
}
.kt-portlet__head-label:before {
content: "";
position: absolute;
bottom: 0;
right: 0;
height: 30px;
width: 15%;
min-width: 50px;
padding-top: 100px;
padding-bottom: 15px;
background-image: linear-gradient(90deg, hsla(0, 0%, 100%, .3), #fff);
}
.kt-portlet__head-toolbar>div>div {
padding: 1rem 1.2rem;
background-color: #1075dd;
height: 80%;
border-radius: 8px;
}
.btn.btn-brand {
color: white;
text-decoration: none;
}
<div class="kt-portlet__head">
<div class="kt-portlet__head-label">
<h3>
This is a really long campaign name that should faaaaaaaade out when it reaches the Statistics button
</h3>
</div>
<div class="kt-portlet__head-toolbar">
<div>
<div>
<a href="#" class="btn btn-brand">
<span>This is a button - text fade out from there sefesfsfsffsfesfs sefesfsfsffsfesfs</span>
</a>
</div>
</div>
</div>
</div>
The :before element with the linear gradient including a transparency change is the right way to go. Here's an example for it:
.kt-portlet__head {
overflow-x: hidden;
position: relative;
}
.kt-portlet__head-label h3 {
white-space: nowrap;
}
.kt-portlet__head-toolbar {
position: absolute;
right: 0px;
text-align: center;
width: 100px;
top: 0px;
}
.kt-portlet__head-toolbar:before {
content: '';
display: block;
position: absolute;
left: -60px;
width: 60px;
height: 100%;
background: linear-gradient(to right, #ffffff00, #ffffffff 90%);
}
<div class="kt-portlet__head">
<div class="kt-portlet__head-label">
<h3>
This is a really long campaign name that should faaaaaaaade out when it reaches the Statistics button
</h3>
</div>
<div class="kt-portlet__head-toolbar">
<div>
<button>
<a href="#" class="btn btn-brand">
<span>This is a button</span>
</a>
</button>
</div>
</div>
</div>
And with something like that ?
.kt-portlet__head {
position: relative;
}
.kt-portlet__head-label {
white-space: nowrap; /* force to keep it in one line */
overflow: hidden; /* do not go outside the container */
}
.kt-portlet__head-toolbar {
display: flex;
position: absolute; /* force the button to be at the complete right */
top: 0;
right: 0;
bottom: 0; /* top & bottom ensure the button take the available height */
align-items: center;
align-content: flex-end;
}
.kt-portlet__head-toolbar::before {
display: block;
content: '';
width: 3em; /* Needed, give a size to the fade effect */
height: 100%; /* Needed to force the gradient to take the whole height */
background-image: linear-gradient(to left, white 0%, transparent 100%);
}
.btn { /* presentation style */
background-color: black;
border-radius: 3px;
padding: 1ch;
color: white;
text-decoration: none;
}
<div class="kt-portlet__head">
<div class="kt-portlet__head-label">
<h3>
This is a really long campaign name that should faaaaaaaade out when it reaches the Statistics button
</h3>
</div>
<div class="kt-portlet__head-toolbar">
<div>
<div>
<a href="#" class="btn btn-brand">
<span>This is a button - text fade out from there</span>
</a>
</div>
</div>
</div>
</div>
You could use box-shadow like this:
.btn { /* presentation style */
box-shadow: -30px 0px 15px 0px white;
}
See fiddle (the red version shows the shape, extent and opacity of the white overlay):
I have a div with a fixed position containing an image that I have set to max-width:20% so it is scaled down. The height of the div is scaled to match the image but the width isn't, it looks like it's the same width of the initial size of the image.
I might be missing something fundamental but can't really understand this.
#logo {
max-width: 20%;
}
#logoholder {
position: fixed;
left: 10px;
top: 120px;
background: rgb(47 47 47 / 36%);
text-align: center;
}
#logo2 {
max-width: 77px;
}
#logoholder2 {
position: fixed;
width: 77px;
height: 77px;
left: 10px;
top: 30px;
background: rgb(47 47 47 / 36%);
text-align: center;
}
<div id="logoholder">
<img id="logo" src="https://www.google.com/gmail/about/static-2.0/images/logo-gmail.png">
</div>
<-- Expected result -->
<div id="logoholder2">
<img id="logo2" src="https://www.google.com/gmail/about/static-2.0/images/logo-gmail.png">
</div>
#logo{
max-width:100px;
}
#logoholder {
position: fixed;
left:0;
top:0;
background: rgb(47 47 47 / 36%);
}
<div id="logoholder">
<img id="logo" src="https://www.google.com/gmail/about/static-2.0/images/logo-gmail.png">
</div>
The max-width using a percentage is causing weird behaviour, changed it to px.
I set some margins and borders for clarity - and left the original images in place (the first one is the one in play here)
I would suggest using a flex display for simplicity then we can set the container to a size and the height of the image to what we want relative to that (see comments in the CSS)
I set the button at the "top" but it could be relative position also and work around that "fixed" position issue.
body {
margin: 0;
}
#logoholder {
position: relative;
left: 10px;
top: 1rem;
/* background: rgb(47 47 47 / 36%);*/
/* light violet background */
background-color: #8080FF20;
}
#logo {
max-width: 20%;
}
#logoholder2 {
position: relative;
left: 10px;
top: 30px;
*/ width: 77px;
height: 77px;
/* light cyan background */
background-color: #20E0E020;
}
#logo2 {
max-width: 77px;
}
/* set up the blocks to keep the "gray" one at the top */
.container-all {
display: flex;
align-items: cemter;
justify-content: cemter;
/*stack then for this demo */
flex-direction: column;
/* the "lime" border around all the content */
border: solid 1px #88ff88;
}
.container-all .content-container {
margin: 0.5rem;
/* get our logo (first container) at the top if we want to */
/* margin-top:0;*/
}
.logo-container {
/* keep logo/button at top when scrolling for this demo */
align-self: flex-start;
position: sticky;
top: 0;
/* set up this containers display */
display: flex;
justify-content: center;
align-items: center;
}
.logo-container .content-item {
/* controls the height of the image on the button */
/* these should be the same since the "default" is 16px font-size == 1rem */
font-size: 1rem;
/* font-size:16px;*/
}
.logo-image {
/* controlled by container font size as these have em */
/* so if 1rem = 16px this 4em would be 16 X 5=80px */
height: 5em;
}
.content-container {
text-align: center;
border: 1px solid blue;
object-fit: contain;
}
.content-container:first-of-type {
/* light gray background for this demo */
/* alpha transparency information into the hex format for colors 2E as this has 8 characters */
background-color: #8080802E;
border: outset #D0D0D02E 4px;
}
.content-item {
border: dashed #00000044 1px;
padding: 0.25rem;
margin: 0.25rem;
}
.content-container .content-item .big-me:last-of-type {
height: 20rem;
}
<div class="container-all">
<div class="logo-container content-container">
<button type="button" class="content-item">
<img class="logo-image" src="https://www.google.com/gmail/about/static-2.0/images/logo-gmail.png">
</button>
</div>
<div class="content-container">
<div class="content-item">
Below here just to force scrolling on the sticky icon
</div>
</div>
<div id="logoholder" class="xcontent-container">
<div class="content-item">
<img id="logo" src="https://www.google.com/gmail/about/static-2.0/images/logo-gmail.png">
</div>
</div>
<div class="content-container">
<div class="content-item">
<-- Expected result -->
</div>
</div>
<div id="logoholder2" class="content-container">
<div class="content-item">
<img id="logo2" src="https://www.google.com/gmail/about/static-2.0/images/logo-gmail.png">
</div>
</div>
<div class="content-container">
<div class="content-item">
<div class="big-me">I am big so I can force the scroll.
</div>
</div>
</div>
</div>
I have something like this
<div class="container">
<div class="img-container">
<img class="thumbnail" src="https://via.placeholder.com/250x250" />
<div classe="img-icon-container">
<i class="photo-icon fas fa-camera-retro" />
<span>10</span>
</div>
</div>
</div>
.container{
height: 200px;
display: flex;
margin-bottom: 20px;
.img-container {
position: relative;
.thumbnail {
height: 100%;
}
.img-icon-container {
position: absolute;
bottom: 0;
width: 100%;
left: 0;
background-color: rgba(110, 110, 110, 0.8);
i {
margin-left: 5px;
margin-right: 5px;
font-size: 20px;
color: white;
}
&:hover {
background-color: blue;
}
}
}
}
In chrome it looks as I wanted.
but in IE 11 & FF
What do I need to add to keep the gray bar contained in the div?
Instead of width:100%; just add right:0;. This will always keep the edges of the inner box against the left and right sides.
The problem is the fixed height of the .container. If you have control of the sizing of these images I would just remove the fixed height of the .container and display: block; on the image to remove the spacing under it.
If you need it to accomodate varying aspect ratios then it's more complicated and there's never a perfect solution that looks neat.
When the browser window is resized, the borders are shifting away from the content?
How can I achieve a design where the border remains in one place, no matter the height of the window?
.story_header {
position: relative;
display: flex;
justify-content: center;
}
.story_header:before,
.story_header:after {
content: '';
width: 100px;
position: absolute;
border: 2px solid black;
margin-top: 20px;
left: 35%;
}
.story_header:after {
right: 35%;
left: auto;
}
<div class='section_1'>
<div class="grid-x">
<div class='large-12 cell'>
<h2 class='story_header'>Our Story</h2>
</div>
</div>
You need to wrap the 'Our Story' to an element let's say span then add the pseudo elements on that span. Try this:
CSS:
.story_header{
position:relative;
display:flex;
justify-content: center;
}
.story_title{
position:relative;
}
.story_title:before, .story_title:after{
content:'';
width:100px;
position:absolute;
border:2px solid black;
margin-top:20px;
}
.story_title:before{
right:100%;
}
.story_title:after{
left:100%;
}
HTML:
<div class="grid-x">
<div class='large-12 cell'>
<h2 class='story_header'> <span class="story_title">Our Story</span></h2>
</div>
</div>
I have this hamburger I'm creating. I'm trying to understand how to position the bars with precise calculation without eyeballing it. The hamburger height is 24px
so I would assume in order to position the middle bar it would be half the height so 12px(top: 12px;) or incase of the example 0.5em but that doesn't look centered to the overall menu. (top: 10px looks right or 0.625em).
Overall whats a better way to calculate anything in css?
http://codepen.io/anon/pen/Bjjqez
<div class="hamburger">
<div class="hamburger__top"></div>
<div class="hamburger__middle"></div>
<div class="hamburger__bottom"></div>
</div>
SASS
.hamburger {
position: relative;
width: 3em;
height: 1.5em;
cursor: pointer;
div {
background-color: red;
position: absolute;
width: 100%;
height: .25em;
}
&__top {
top: 0;
}
&__middle {
background-color: green;
top: 0.5em;
}
&__bottom {
bottom: 0;
}
}
Flexbox can do that....no positioning required.
Here's a couple of options.
.hamburger {
width: 3em;
height: 1.5em;
cursor: pointer;
display: flex;
flex-direction: column;
margin: 1em auto;
}
.hamburger div {
background-color: red;
height: .25em;
}
.around {
justify-content: space-around;
background: lightblue;
}
.between {
justify-content: space-between;
background: lightgreen;
}
<div class="hamburger around">
<div class="hamburger__top"></div>
<div class="hamburger__middle"></div>
<div class="hamburger__bottom"></div>
</div>
<div class="hamburger between">
<div class="hamburger__top"></div>
<div class="hamburger__middle"></div>
<div class="hamburger__bottom"></div>
</div>
Replace your top: 0.5em with:
top: 50%;
transform: translateY(-50%);
From my understanding of how this works, the top: 50% will move the top of the element to be half way down. The translateY(-50%) will then move the element up by half it's own height, and therefore centrally position it.
Example: http://codepen.io/anon/pen/RrrqWP