I have some cards with an image and a title below them, where the image and title resize as the card resizes, and the card resizes as the screen size changes. On smaller screens or with longer titles I get a problem where the image covers the text.
I would like the image to scale to fit the card, but stop either when it reaches the width of the card OR the top part of the text. (all images are perfect squares, so img width and height should always be equal)
Here are some screenshots of the results, On the left side are two things that I don't want to happen, and on the right are things that are OK.
link to image examples of cards
Since the complete code is a bit long, here is a JSFiddle with a working example of what it's like now (the cards are in bootstrap styled rows/columns). http://jsfiddle.net/js47withfeeling/dtbx78ay/4/
Below are some relevant code snippets.
HTML of a card
<div class="card-column card">
<img class="card-img" src="Link to Image">
<p class="card-title">With Security</p>
</div>
A bunch of cards like that are inside of this HTML block which applies some bootstrap
<div class="row">
<div id="loadCardsHere" class="col-md-9 12u(mobile)">
<!--cards go here -->
</div>
</div>
relevant CSS
body{
font-family: 'Old Standard TT', serif;
}
.card{
margin-top:5px;
margin-right:5px;
}
.card-img{
width:100%;
max-height:500;
}
.card-title{
position:absolute;
bottom:0;
align-self: center;
font-size:180%;
}
.card-column{
float: left;
width: 32%;
height:300;
cursor: pointer;
border-color: #01ABAA;
border-width: medium;
}
#media screen and (max-width: 600px) {
.card-column {
width: 100%;
}
}
#media (min-width: 768px) {
.card{
max-width:33%;
max-height:auto;
}
}
Is there some sort of CSS attr like " max-height: (parent.height) - (parent.2ndChild.height) "? (That syntax is obviously wrong, but something to that effect)
Popshuvit is correct. Also, align-self is a flex property but there is no flex-parent to give this context. You should take the flex route though. I have not tested, but the result you want will probably look like this:
.card {
position: relative;
display: flex;
flex-flow: column;
text-align: center;
align-items: center;
width: 100%;
}
.card-img {
width: 100%;
object-fit: contain;
}
.card-title {
...text styles
}
Additionally, you seem to have separate styles for .card and .card-column when they are actually the same element. This would only make sense if some of the 'cards' did not include the .card-column class. Continuing down the flex route will also allow yuo to get rid of those pesky floats!
Remove position:absolute; bottom:0; from .card-title. Absolute removes it from the flow, and it has no context as to the height of other divs/elements.
Related
I have some code inside pre and code tags in a bootstrap container that I'd like to scroll horizontally. This normally works fine, until I add a flexbox to my page's body in order to accomplish a sticky footer. After this, the code no longer scrolls horizontally when the page is narrow (such as for mobile viewing).
Here's my code (note that horizontal scrollbars for the code go away as you narrow the window):
html, body {
height: 100%;
}
body {
min-height: 100%;
display: flex;
flex-direction: column;
}
code {
max-height: 200px;
background-color: #eeeeee;
word-break: normal !important;
word-wrap: normal !important;
white-space: pre !important;
}
.flexer {
flex: 1;
}
footer {
background-color: #CCC;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container">
<div class="row">
<div class="col-md-12 docs">
<p>Some sample code</p>
<pre><code>Loading mirror speeds from cached hostfilebase: mirrors.arpnetworks.com * centosplus: mirrors.arpnetworks.com* extras:mirrors.arpnetworks.com*rpmforge: mirror.hmc.eduupdates: mirrors.arpnetworks.comExcluding Packages in global exclude list</code></pre>
</div>
</div>
</div>
<div class="flexer"></div>
<footer>
<div class="container">
<div class="row">
<div class="col-sm-12 text-center">
footer
</div>
</div>
</div>
</footer>
http://jsfiddle.net/nturor46/1/
Any idea how to use flexbox for sticky footers while still maintaining scrolling pre / code?
a simple
.container { width:100%; }
resizes the website correctly. BUT then, Chrome doesn't let you actually use the scrollbar. This is caused by it overflowing the dimension of all of its containers (apart from BODY).
Hence we gotta tell the browser to correctly recognize the pre node:
.container {
max-width: 100%;
}
pre {
position: relative;
}
This tells Chrome to correctly handle mouse events again AND fixes the layout
Please note that the margin-bottom of the pre-node is lost in overflow-country, which could cause your layout to look weird. max-width was used in the final version to make sure it doesn't overwrite fixed width statements made in bootstrap
PS: tested in current Chrome and Firefox http://jsfiddle.net/nturor46/32/
Those bootstrap styles just wreak havoc on natural CSS!
The problem seems to come from a conflict between your column-direction flex container and bootstrap rules. It's basically resulting in the horizontal scrollbar shifting from the pre / code content box to the browser window, when the content box overflows the screen.
With these adjustments, your desired layout seems to work:
make the primary .container div the primary flex container (in your code this role is played by the body element)
move the footer element into this new container
use flex auto margins to stick the footer to the bottom
override bootstrap margin, padding and width wherever necessary
HTML
<div class="container">
<div class="row">
<div class="col-md-12 docs">
<p>Some sample code</p>
<pre><code>Loading mirror speeds from ... cached hostfilebase</code></pre>
</div>
</div>
<footer>
<div class="container">
<div class="row">
<div class="col-sm-12 text-center">
footer
</div>
</div>
</div>
</footer>
</div>
CSS
html, body { height: 100%; }
body > .container {
display: flex;
flex-direction: column;
height: 100%;
width: 100%; /* override bootstrap styles */
padding: 0; /* override bootstrap styles */
}
body > .container > .row {
margin: 0; /* override bootstrap styles */
display: flex; /* nested flex container */
justify-content: center; /* center content box on page */
}
body > .container > .row > .docs {
width: 75%; /* adjust width of the content box here */
}
code {
max-height: 200px;
background-color: #eeeeee;
word-break: normal !important;
word-wrap: normal !important;
white-space: pre !important;
}
footer {
margin-top: auto; /* stick footer to bottom of container */
background-color: #CCC;
}
Revised Fiddle
Tested in Chrome and Firefox.
What happens here is most definitely a bug in Chrome.
After playing around with your Fiddle, and looking at it with other browsers, I can conclude that this is a Chrome-specific problem. And a curious one.
For some reason, <div class="col-md-12 docs"> grows to the size it should have (the height of p and pre together), but doesn't account for the horizontal scrollbar inside the pre tag.
Here's an image to demonstrate the problem. The part with the red background is the container.
Since pre has a border of 1px wide at the bottom, the result leaves a 1px gap for you to actually use the scrollbar. You can try it yourself. Just try to grab the most upper 1px line of the scrollbar.
Removing the flex properties does fix your problem, but we're not going to accept that.
Now, I would've thought that adding a padding of 0.1px to the bottom of the parent would fix the problem, but it didn't. I then tried wrapping the pre tag in a div with class chromefix, and then added the following CSS
.chromefix{
overflow: hidden;
}
But that created an even weirder situation where the container grew with the scrollbar for about 50%
So I tried combining the two, but not a lot of difference there.
This is where I started looking at the pre tag and its properties. It has overflow: auto by Bootstrap default. So what I tried was adding
pre{
overflow-x: scroll !important;
}
And guess what? It worked!
So all you have to do is add overflow-x: scroll !imporant to pre, and you're good to go! Here's a working Fiddle.
Hope this helps
As a sidenote. I think you want to move max-height: 200px to pre as well. It won't work when you've applied it to code.
Problem seems to be with the width of <pre>.
When width of your screen goes below 768px no specific width is applied to the .container by bootstrap hence the issue is occurring.
When width of your screen is above 768px following classes from bootstrap.css come in picture.
#media (min-width: 1200px)
.container {
width: 1170px;
}
#media (min-width: 992px)
.container {
width: 970px;
}
#media (min-width: 768px)
.container {
width: 750px;
}
As you can see once the width goes below 768px there is no specific width given.
To counter this issue, you have to write your css, something like this.
#media (min-width: 480px) {
.container {
width: calc(100% - 40px);
}
}
Basically, you have to specify width for .container when screen width goes below 768px. Once you do, it will fix your issue.
Wrap the prev tag and its content with div like below.
<div class="code">{your code goes here}</div>
css :
.code{
width:92vw; /*you can change this in media query to specific device width for better results*/
overflow-x:auto;
}
Working jsfiddle link
I've been working on a website to put my portfolio in for a bit. I tried to keep a pretty simple design since the website itself is not supposed to be the center of attention, but I would still like it to be responsive so pretty much anyone can access it.
On the homepage, I would like to display four (4) previews of my best 3D renders.
The idea is simple :
-Organized in a 2x2 grid
-Centered in the parent container
-Images resize to fit the parent container
For visual people, here's an album with a concept and 3 screenshots demonstrating my issue : http://imgur.com/a/Hce4o
My issue is that the images resize only when I adjust the window horizontally, and not vertically. Meaning if the viewer has a wide screen, the bottom two previews will be partially to completely cut out.
As you can see, the images only change when the width of the window is fiddled with, but not the height. Here's my code.
HTML
<div id="container">
<table id="bestsamples">
<tr><td><figure><img class="homethumbnail" src="./img/home_thumbnails/thumbnail.jpg" alt="Thumbnail Sample"></img><figcaption>Sample 1</figcaption></figure></td>
<td><figure><img class="homethumbnail" src="./img/home_thumbnails/thumbnail.jpg" alt="Thumbnail Sample"></img><figcaption>Sample 2</figcaption></figure></td></tr>
<tr><td><figure><img class="homethumbnail" src="./img/home_thumbnails/thumbnail.jpg" alt="Thumbnail Sample"></img><figcaption>Sample 3</figcaption></figure></td>
<td><figure><img class="homethumbnail" src="./img/home_thumbnails/thumbnail.jpg" alt="Thumbnail Sample"></img><figcaption>Sample 4</figcaption></figure></td></tr>
</table>
</div>
CSS
#container{
position:relative;
height:100%;
background:#6b6b6b;
overflow:hidden;
z-index:0;
}
#bestsamples{
margin:0 auto;
padding:1em;
}
#bestsamples a{
text-decoration:none;
}
#bestsamples figure{
margin:1em;
}
#bestsamples figcaption{
position:relative;
margin-top:-2.5em;
padding-left:16px;
height:2.5em;
font-family:'Titillium Web', sans-serif;
font-size:1em;
font-weight:600;
line-height:2.5em;
color:#a3a3a3;
background-color:rgba(0, 0, 0, .5);
transition:.25s ease;
}
#bestsamples figure:hover figcaption{
padding-left:32px;
transition:.25s ease;
}
.homethumbnail{
max-width:100%;
}
I tried using max-height instead as well as setting height/width to auto, to no avail.
Does anyone know how to make it work ?
I would also greatly appreciate if you had a more efficient/cleaner way to organize this other than using a table.
Thank you in advance ! Have a nice day.
My suggestion is to take it out of a table which isn't really designed for layout anymore. Tables can be tough to style responsively. So my suggestion is to try something like this:
<div class="container">
<figure>
<img src='http://placekitten.com/g/500/500'>
<figcaption>Image 1</figcaption>
</figure>
<figure>
<img src='http://placekitten.com/g/500/500'>
<figcaption>Image 2</figcaption>
</figure>
<figure>
<img src='http://placekitten.com/g/500/500'>
<figcaption>Image 3</figcaption>
</figure>
<figure>
<img src='http://placekitten.com/g/500/500'>
<figcaption>Image 4</figcaption>
</figure>
</div><!-- end container -->
Style something like this:
.container {
width: 40%;
margin-left: auto;
margin-right: auto;
}
.container figure {
float: left;
width: 45%;
max-width: 250px;
margin: 0 0 50px 5%;
}
.container figure:nth-child(1),
.container figure:nth-child(3) {
margin-left: 0;
}
.container figure img {
max-width: 100%;
float: left;
}
I have a live example here on codepen. Hope this helps.
Creating a media query for large screens is an acceptable option to account for this. Media queries let you apply CSS only when your screen is greater than or less than a certain width. Using all the same code from my previous answer, plus you could do something like...
#media screen and (min-width: 1200px) {
.container {
width: 80%; /* make the container larger */
overflow: hidden;
}
.container figure {
width: 22%;
max-width: 100%;
margin-left: 4%;
}
.container figure:nth-child(3) {
margin-left: 4%;
}
}
min-width inside the media query means 'apply this css as long as the width of the browser is a minimum of the number provided. So anything greater than or equal to 1200px will get the css, thus, targeting larger screens only.
This will let all the images sit on one row since the extra real-estate is available. I updated the live example to also reflect this code.
Hope either this solution or the one I suggested in the comments helps you out!
I need to get 3 row layout in HTML + CSS in my Angular.js app.
It should work like this:
My problem is when I resize my middle div get onto my top bar.
Here's some of my code:
.top-pos {
&.small {
padding-bottom: 130px;
}
&.big {
padding-bottom: 170px;
}
}
.bottom-pos {
bottom: 10px;
right: 0;
width: 100%;
position: absolute;
}
.middle {
#include align(vertical);
width: 100%;
}
HTML
<div class="top-pos small">
<div class="position-container">
<div class="top">
<h1 class="title">Some title</h1>
</div>
<div class="middle">
<input type="text" />
<input type="text" />
</div>
</div>
</div>
<div class="bottom-pos">
<button class="submit">Search</button>
</div>
Generally the top bar div should be always on top of the page, the bottom bar should be ALWAYS on bottom and the middle should be always on the middle between top and bottom bar. And the scrollbar should appear when all the elements are like on the second picture.
If older browser support is not an issue you could use css3 flex box to achieve something like this (not exact replica of the images):
#container{
display:flex;
flex-flow:column;
justify-content:space-around;
align-items:center;
width:50%;
height:100%;
}
#container div {
width:90%;
color:#fff;
background:black;
}
#top,#bottom{
height:50px;
}
#middle{
height:100px;
}
Demo
I have created a Fiddle which uses media queries to solve your problem. Hope that helps
CSS:
#media (min-width:400px) {
.top,.middle{
margin-bottom:20px
}
}
#media (max-width:399px) {
.top,.middle{
margin-bottom:2px;
}
h1{
margin:0;
}
}
For creating grid-like layouts that respond to window size changes, you should really consider Bootstrap. It allows you to very easily define layouts that are responsive to the window size. It also really nicely works together with Angular, since Angular defined directives that replace the Javascript part of Bootstrap. However, if you are only interested in the Grid layout part of Bootstrap, you do not need any Javascript at all, since it is all defined in CSS. See this link for more info on the Grid layout of Bootstrap:
http://getbootstrap.com/examples/grid/
I am making a fairly simple responsive website. I have a logo div that keeps the logo centered on small screens, and to the left on big screens. Everything is working how I want it to, (try resizing the jsfiddle) except that I want the logo div to scale down to it's min-width before the links wrap to the next line. I'm not sure how to word this, but I want the logo div to resize based on if the links are pushing it (if they have enough room). When it reaches it's min-width, then the links should wrap. Not sure if this is possible, but I figured I'd ask anyway.
Here is the jsfiddle.
The html:
<div class="header">
<div class="logo">logo</div>
<div class="link">link one</div>
<div class="link">link two</div>
<div class="link">link three</div>
</div>
The css:
.header {
text-align: center; /* Centers the logo text, and centers the links between the logo div and the other side of the page.*/
}
.logo {
max-width: 300px;
min-width: 100px;
width: 100%; /* It is always the min-width without this*/
background-color: red;
display: inline-block;
float: left;
}
.link {
display: inline-block;
background-color: green;
}
I hope I was clear, I'm still learning. Let me know if I need to add any more details.
I went looking some more and found flexboxes. Got them to do exactly what I wanted.
http://jsfiddle.net/3525C/10/
My new HTML:
<div class="header">
<div class="logo">logo</div>
<div class="nav">
<div class="link">link one</div>
<div class="link">link two</div>
<div class="link">link three</div>
</div>
</div>
and CSS:
.header {
text-align: center;
display: flex;
flex-flow: row wrap;
}
.logo {
flex: 1 0 auto;
min-width: 100px;
background-color: red;
}
.nav {
flex: 1 1 auto;
background-color: lightgray;
text-align: center;
}
.link {
display: inline-block;
background-color: green;
}
Thanks hexalys for helping me get it working.
The only real thing that responds the way you're talking is a table. Table cells have the capability of being flexible with their width.
You can use CSS to make this happen. It's a more modern display, so not all browsers (looking at you, older IE) will support it. But this should get you started: http://jsfiddle.net/mfvf8/
Here's what I added as a proof of concept:
.header
{
display: table;
width: 100%;
}
.header > div
{
display: table-cell;
}
.header .link
{
white-space: nowrap;
width: 1px;
}
I set the header to be displayed as a table, and gave it full width. I made all of the child divs act like a table cell. I made the links minimum width (1px) and said not to wrap whitespace. With regular divs, that would overflow. With table cells, that means it tries to be 1px wide but will expand to fit its content.
The rest of a table row's width will go evenly to whichever cells are left over that don't have a set width. In this case, it's the logo div. Then, as you shrink the window, it will slowly start to shrink the logo as needed.
You will need to tweak this to fit your design better. If you don't want your nav pushed all the way to the right like it is in the jsfiddle, you might need a "buffer" div to the far right, or different width settings, or a set max-width on the header div.
I'm not one to usually ask, but I cannot seem to get this done using CSS/CSS3.
Note, i'll be happy even with a not-so-supported CSS3 style, like resize.
The jsFiddle for it.
The current unresizable code:
HTML:
<div id="boxes">
<a id="about1" class="aboutbox" href="/property-for-sale">
</a>
<a id="about2" class="aboutbox" href="/why-cyprus"> </a>
<a id="about3" class="aboutbox" href="/why-zantis"> </a>
<span class="stretch"> </span>
</div>
CSS:
#boxes {
padding: 70px 0 70px 0;
text-align: justify;
-ms-text-justify: distribute-all-lines;
text-justify: distribute-all-lines;
}
.aboutbox {
padding: 0;
margin: 0;
display: inline-block;
*display: inline;
zoom: 1;
width: 320px;
height: 225px;
vertical-align: top;
text-align: left;
background-size: auto auto;
}
#about1 {
background:#000 url('http://zantisgroup.com.cy/templates/oneweb/images/SEA_FRONT.jpg') no-repeat center center;
}
#about2 {
background:#000 url('http://zantisgroup.com.cy/templates/oneweb/images/SEA_FRONT.jpg') no-repeat center center;
}
#about3 {
background:#000 url('http://zantisgroup.com.cy/templates/oneweb/images/SEA_FRONT.jpg') no-repeat center center;
}
#about1:hover {
background:#000 url('http://zantisgroup.com.cy/templates/oneweb/images/SEA_FRONT_a.jpg') no-repeat center center;
}
#about2:hover {
background:#000 url('http://zantisgroup.com.cy/templates/oneweb/images/SEA_FRONT_a.jpg') no-repeat center center;
}
#about3:hover {
background:#000 url('http://zantisgroup.com.cy/templates/oneweb/images/SEA_FRONT_a.jpg') no-repeat center center;
}
If you resize the html panel, you'll see that they float as expected. I'm using a common method to distribute them equally along the parent div. I'm also using CSS to create a image button with hover effects (don't ask about the nature of the graphics ..).
I'd like to get these to resize accordingly when the html panel is resized; i.e. get the actual button to scale down and remain in one line.
I've got a working solution with jQuery, but spent my time getting this without it and got nowhere. Any ideas?
tia.
Aspect ratio
The main issue here is maintaining the relative dimensions of the images (the aspect ratio). A couple potential ways to do this without using JavaScript or jQuery are as follows:
Using foreground images (img tags).
Using calc() to make the height of the image wrapper be a fixed % of its width.
I didn't have much luck with calc(). The closest I got was attempting to make the height a fixed % of the viewport width (using the vw unit). It didn't seem very promising. I can't entirely rule out a solution being possible using calc(), but so far the only obvious CSS solution for maintaining the aspect ratio requires the use of foreground images.
Updated Demo
Hover state for foreground images
Achieving the hover effect using foreground images is fairly simple. Add a pair of images to each image wrapper, and apply the :hover pseudo-class to the wrapper to turn each image on or off as needed.
<a class="aboutbox" ...>
<img class="off" src="..." alt=""/>
<img class="on" src="..." alt=""/>
</a>
...
.aboutbox:hover img.off { display: none; }
.aboutbox img.on { display: none; }
.aboutbox:hover img.on { display: inline-block; }
Justifying images
The trickiest part of justifying the images is that there needs to be some whitespace between the image wrappers (in the HTML source code) for the justification to have a chance of working, for the same reason that words in a sentence need to have whitespace between them (otherwise, they'll be treated as a single word).
But whitespace between inline-block elements in the HTML source code causes 3-4px of horizontal spacing to be added between the elements (with no CSS solution available for avoiding it that's truly cross-browser and safe). That extra space, although necessary for the justification to work, is mostly likely unwanted visually and may prevent all of the images from fitting on the same line in some cases.
Here's an initial demo with a crude solution: limiting the width of each image to 31%, to allow enough room (on most screen sizes) for the whitespace between the image wrappers.
The other issue with justifying the images is that, as with text, justifying images only works if the content spans at least 2 lines. One workaround for this is to add a span tag at the end of the content with display:inline-block and width:90%. The initial demo demonstrates this.
#media queries
It's worth noting that the justification is only needed when the screen is wide enough to allow extra space between the images. #media queries can be used to only apply the justification on large screens. On small screens, the image wrappers can be floated so that there's no extra space between them.
Updated demo using #media queries
One solution is to replace the background image with an actual image. And use css to control what image is displayed, and to resize based on the containing elements. So you wrap each link in a div, which re-sizes based on your boxes container. Using css you set the image url using the content: selector.
http://jsfiddle.net/CPNbS/6/
Your resulting html looks something like:
<div id="boxes">
<div class="link" id="about1">
<a class="aboutbox" href="/property-for-sale"><img /></a>
</div>
<div class="link" id="about2">
<a class="aboutbox" href="/why-cyprus"><img /></a>
</div>
<div class="link" id="about3">
<a class="aboutbox" href="/why-zantis"><img /></a>
</div>
</div>
and the css:
.link{width:30%;height:100%;border:1px solid green;display: inline-block;
*display: inline;
zoom: 1;}
.link a{padding: 0;
margin: 0;
display:block;
width: 100%;
height:100%;
vertical-align: top;
text-align: left;
background-size: auto auto;}
.link a img{max-width:100%;}
#about1 a img{
content:url("http://zantisgroup.com.cy/templates/oneweb/images/SEA_FRONT.jpg");
}
#about2 a img{
content:url("http://zantisgroup.com.cy/templates/oneweb/images/SEA_FRONT.jpg");
}
#about3 a img{
content:url("http://zantisgroup.com.cy/templates/oneweb/images/SEA_FRONT.jpg");
}
#about1:hover a img,#about2:hover a img,#about3:hover a img{
content:url("http://blogs.mathworks.com/pick/files/zebrainpastelfield.png");
}
You could also use a responsive design technique by including media queries. But this is more for different devices rather than re-sizing, so does not look as 'fluid'.
Hope this helps...
To do this with background images as you've set it up, you have to get rid of the width setting on the each item, and size the background image with background-size: 100% 100%; To maintain the height to width proportion of the .aboutboxes, use the intrinsic ratio method here with a percentage based padding-bottom. More here: http://alistapart.com/article/creating-intrinsic-ratios-for-video
.aboutbox {
position: relative;
padding-bottom: 70.3125%;
display: block;
width: auto;
height: 0;
background-size: 100% 100% !important;
}
If you'd like you can include a max-width or padding on the wrapper to limit how far they stretch.
Updated your fiddle here: http://jsfiddle.net/carasin/s4pUe/11/
Just be aware of some limited IE support of background-size: http://caniuse.com/#feat=background-img-opts
#boxes {
white-space: nowrap;
}
boxes a{
display:inline-block;
width: 33%;
background-size: cover;
}
but I'd rather use img tag see http://jsfiddle.net/Vicky_007/GZMvT/14/
and you can also emulate table:
#boxes {
display: table;
width: 100%;
table-layout:fixed;
}
#boxes a{
display:table-cell;
background-size: cover;
}