I am beginning to dabble in responsive design, and as a result am trying to pinpoint best practices in my CSS. I am working on placing caption text over what will eventually be a custom, jquery driven image slider.
All of this is running at http://www.taylorp0994.net/websites/cincoschool/index.html, so please look to the live results and code for further information.
I have achieved what appears to be a workable solution; however, I fear it is not semantic to use pixels, regardless of context. How can I use percentages to achieve the same look and what approach should I take, (margin-top, position:relative/top, etc.)? I've yet to have much success with any of the obvious except for my current solution which is to position:relative the caption box and move it up via top:-46.5px.
The work you've posted looks really promising!
Two things worth mentioning from my cursory look:
There's nothing particularly 'wrong' with using pixel measurements. The only time this will potentially become a problem for you is with the caption's length. If the text is likely to change length (and thus: roll onto two lines), then using a set height adjustment won't work.
There's a lot of empty 'p' tags within the caption, is that deliberate?
The way I tend to tackle this type of task is to use positioning:
Have a single div wrap that contains both the image and the caption. Position this relative;
Set the image z-index to a low number;
Set the caption's z-index higher, and set to position: absolute, bottom: 0. This will position the caption off the bottom edge of the parent div, which will in turn inherit it's height from the image.
Two secs and I'll post an example.
Here you go: http://jsfiddle.net/HhuhR/ This is very quick-and-dirty but should help put you on the right track:
<style>
.img-wrap{
width: 60%; /*just here for the preview */
position: relative;
}
.img-wrap img{
max-width: 100%;
z-index: 1
}
.img-wrap .caption{
display: block;
width: 100%;
position: absolute;
bottom: 5px; /*if using padding in the caption, match here */
left: 0;
z-index: 2;
margin: 0;
padding: 5px 0;
text-indent: 5px;
color: #fff;
font-weight: bold;
background: rgba(0, 0, 0, 0.4);
}
</style>
<div class="img-wrap">
<img src="http://taylorp0994.net/websites/cincoschool/img/slide1.png" alt= "">
<span class="caption">Lorem ipsum dolor sit amet</span>
</div>
Do remember that as your viewport width gets narrower, the caption text will dominate the image (as the image itself gets smaller). I tend to identify a point in my design where this becomes a problem and simply overwrite the caption position for bottom/left and set position: relative - this drops the caption directly beneath the image rather than over-lapping (and potentially fully covering) it.
Related
I have an interesting issue I've never encountered in css before. A client is asking if the first blue box in the image below can crop after the word "Association" instead of spanning the full width of the parent.
That's an inline-block element with width set to auto.
display: inline-block;
width: auto;
padding: .5em;
Nothing special, right? As you can see by box 2, The director of marketing has his title cropped correctly. So why is it that css chooses to display the blue background nearly the full width of the parent when the text requires more than one line?
Does anyone know of some css property that can be applied to make an inline-block element crop at the end of words? Forgive if I am failing to articulate this. I'm not really sure how to structure this question.
If it helps to know, I cannot make a special case for this item. It is a CMS based system and the job titles can be anything. Making a special case, like max-width:90% wouldn't work, especially considering mobile break points and such. We would have to write cases for anything with a long title, and specific to that title's unique set of words, so that's pretty much out of the question.
Here's a fiddle to mess with if you want to see it in action. They styles are pretty much the same, at least the important parts.
https://jsfiddle.net/4f7jj7L8/
If the CMS entry itself can have the line break (not a br tag but a normal linebreak), then there's a simple solution:
CSS:
.job > h5 {
white-space: pre-line;
}
HTML (Generated):
<h5>Director
of Association Management Services</h5>
Demo: https://jsfiddle.net/4f7jj7L8/4/
Not automatically.
The width of an inline-block is defined as
If 'width' is 'auto', the used value is the shrink-to-fit width as for
floating elements.
Calculation of the shrink-to-fit width is similar to calculating the
width of a table cell using the automatic table layout algorithm.
Roughly: calculate the preferred width by formatting the content
without breaking lines other than where explicit line breaks occur,
and also calculate the preferred minimum width, e.g., by trying all
possible line breaks. CSS 2.1 does not define the exact algorithm.
Thirdly, find the available width: in this case, this is the width of
the containing block minus the used values of 'margin-left',
'border-left-width', 'padding-left', 'padding-right',
'border-right-width', 'margin-right', and the widths of any relevant
scroll bars.
Then the shrink-to-fit width is: min(max(preferred minimum width,
available width), preferred width).
If the text is long enough, the preferred width will be greater than the available width. So the inline-block will fill all the available width.
However, you can avoid that inserting explicit line breaks (e.g. <br />) at the desired places.
.job {
width: 45%;
float: left;
margin-right: 2%;
}
.image {
width: 100%;
height: 100px;
background: #000;
}
h2 {
font-size: 1.2em;
}
h5 {
display: inline-block;
padding: .5em;
font-size: 1em;
background: #ff0000;
}
p {
margin-top: 1em;
}
<div class="job">
<div class="image"></div>
<h2>Some Name</h2>
<h5>Director<br />of<br />Association<br />Management<br />Services</h5>
<p>Lorem ipsum dolor set amit</p>
</div>
<div class="job">
<div class="image"></div>
<h2>Some Name</h2>
<h5>Director of Sales</h5>
<p>Lorem ipsum dolor set amit</p>
</div>
Yes, it is possible — the highlight effect can be cleverly emulated using a mix of:
Declaring the element as inline, so it collapses to content width
Using a combination of box shadows to cover all four edges
Using relative positioning and a left offset to compensate for extra space taken up by the box shadow
Here's the minimal CSS that works:
h5{
display:inline;
font-size:1em;
line-height: 1.75em;
position: relative;
left: .5em;
background:#ff0000;
box-shadow: 0 -.25em 0 .5em #ff0000,
0 .25em 0 .5em #ff0000,
.25em 0 0 .25em #ff0000,
-.25em 0 0 .25em #ff0000;
}
And it looks like this on Chrome v41, OS X 10.10.3:
See fiddle here: https://jsfiddle.net/teddyrised/4f7jj7L8/2/
I have a glyphicon as such:
<div class="col-xs-4 col-sm-2">
<span class="glyphicon glyphicon-circle-arrow-up glyphicon-large"></span>
</div>
.glyphicon-large {
min-height: 260px;
font-size: 35px;
width: 1em;
display: block;
top: 50%;
margin: -0.5em auto 0px;
}
The glyphicon won't align to the center, vertically. When I open firefox, inspect element, and toggle off/on the top 50% rule, it suddenly works. How come?
Browser Bug Explanation
According to MDN on top:
For relatively positioned elements (those with position: relative), it specifies the amount the element is moved below its normal position.
Note: Percentage is applied as a percentage of the height of the element's containing block
According to W3 on top:
For relatively positioned boxes, the offset is with respect to the top edges of the box itself (i.e., the box is given a position in the normal flow, then offset from that position according to these properties).
Note: Percentages refer to height of containing block
Here's my guess:
I think what's happening is that when the browser is first rendering the visual tree, and sees top:50%;, it looks to the parent to set the height. Since no height has been specifically applied, and it has not loaded any child contents, the height of this div (and all divs) effectively starts off as zero until otherwise indicated. It then pushes down the glyph by 50% of zero.
When you toggle the property later, the browser has already rendered everything, so the calculated height of the parent container is provided by the height of its children.
Minimal, Complete, and Verifiable Example
Note: This doesn't really have anything to do with Bootstrap or Glyphicons. In order to avoid a dependency on bootstrap, we'll add top: 1px that would have been applied by the .glyphicon class. Even though it is overwritten by 50%, it still plays an important role.
Here's a simple set of parent/child elements:
<div id="container">
<div id="child">Child</div>
</div>
In order to simulate the toggling the property in a more repeatable fashion, we can just wait two seconds and then apply a style in javascript like this:
window.setTimeout(function() {
document.getElementById("child").style.top = '50%';
},2000);
Example 1 (jsFiddle)
As a starting point, let's recreate your issue.
#container {
position: relative;
/* For Visual Effects */
border: 1px solid grey;
}
#child {
position: relative;
height: 50px;
top: 1px;
/* For Visual Effects */
border: 1px solid orange;
width: 50px;
margin: 0px auto;
}
Notice that as soon as you resize the window, the browser will repaint the screen and move the element back to the top.
Example 2 (jsFiddle)
If you add top: 50% to the child element, nothing will happen when the javascript adds the property because it won't have anything to overwrite.
Example 3 (jsFiddle)
If you add top: 49% to the child element, then the DOM does have something to update so we'll get the weird glitch again.
Example 4 (jsFiddle)
If you add height: 50px; to the container instead of the child, then the top property has something to position against right from the get go and you don't need to use toggle in JavaScript.
How to Vertically Align
If you just wanted to know how to vertically center something consistently, then you can do the following:
The trick to vertically centering text is to set the line-height equal to the container height. If a line takes up 100 pixels, and the line of text online takes up 10, then browsers will try to center the text within the remaining 90 pixels, with 45 on the top and bottom.
.glyphicon-large {
min-height: 260px;
line-height: 260px;
}
Solution in jsFiddle
Tried centering a glyph icon that was inside an H1 tag, that was taking a while - so I discovered that you can actually change the font size and colour inside the SPAN tag contaning the glyph.
Thus:
<h1><span class="glyphicon glyphicon-envelope" style="font-size: 24px; color: #108db7;"></span> Mes Messages</h1>
actually worked out for me.
Have you tried ? :
<span class="glyphicon glyphicon-circle-arrow-up glyphicon-large" style="vertical-align:middle"></span>
This is my first question, I don't think I'm doing something wrong asking it, as it's specific, I'm trying to do a gallery, this gallery has pages, each of which has a caption, I need to show an image with 16:9 ratio and the caption no matter how long it's.
As it's right now, it can show the caption, but when we resize the browser to a smaller breakpoint, if the caption is too long it will just break (will show the caption but maybe not the image if the caption is too long).
That's the solution I'm looking for right now, I'll leave a jsfiddle as an example, I tried to make it the simplest possible, so don't look at the ugly arrows and stuff :P.
fiddle: http://jsfiddle.net/Vb7bP/5/
An ugly fix for this would be to change the padding-bottom here:
.galleryContainer {
padding-bottom: 56.25%; // This is for the image to respect a 16:9 aspect ratio.
}
But that won't work cause it might break if the caption is too long or too short, we might loose our 16:9 ratio.
The caption css I think is fine, it's positioned at the bottom of the div as absolute.
.galleryCaptionWrapper {
background: #ccc;
width: 100%;
position: absolute;
padding: 25px;
z-index: 3;
bottom: 0;
}
Any kind of help will be much appreciated, sorry if the question is wrong. Thanks!
Is this what you're looking for?
http://jsfiddle.net/Vb7bP/3/
I think you had absolute positioning on a lot of things where you didn't need it. Pertinent css is here:
.galleryImageWrapper {
background-color: #000;
width: 100%;
padding-bottom: 56%;
position: relative;
}
.galleryImageWrapper img {
position: absolute;
width: 100%;
top: 0;
left: 0;
height: 100%;
}
I had a similar question myself:
Scaling object element height proportional to width + constant with CSS
You don't have to do anything special to make the caption come after the image. That's the standard behavior for block elements.
I've gone through CSS validation (which did find some pesky unclosed tags, sorted now).
I'm trying to align an image to the top right side of my page, with title text on the top left.
I can do this, but when I resize the browser window the image always wants to overlap the title text before either of them resize. If I remove the margins that I've used to place the image then the image sits under the title text (and to the right) instead of just to the right of it, but I feel removing this (while keeping the positioning) might be key. I do need the image to be overlapped by some other elements though.
Here's a snippet of my code for the image:
img#site-logo {
max-width: 100%;
height: auto;
clear: both;
position: relative;
z-index: 0;
margin: -12.87em 2em -16em 0px;
}
And for the site title:
#site-title a {
font-size: 4.875em;
font-weight: bold;
line-height: 78px;
padding: 0px;
margin-right: auto;
white-space: nowrap;
z-index: 2;
position: relative;
}
Site is live here:
http://dominicpalma.com/
There are surely several different approaches to solve your problem.
But in my eyes it would be the best solution to set a min-width for your #page element.
#page{
min-width:900px;
}
I have played a little bit around with the width and think a min-width of 900 px fits best in your case.
I have a div within a div. I want one to extend out of the shell div so it resembles a tab. I thought just using absolute positioning with a negative value would push it out of the parent div. That doesn't seem to work. Is there a CSS work-around?
Example
http://jsfiddle.net/W3CyT/
http://jsfiddle.net/iambriansreed/W3CyT/4/
CSS
#sideWall {
height:100px;
width:100px;
position:absolute;
top: 10;
left: 10;
background: black;
margin-top: 60px; /* give room for tab */
}
.showSideWall {
height: 60px;
width: 30px;
position: absolute;
top: -60px; /* move tab above container */
right: 0;
background: red;
}
You're doing it correctly, however, you need to rethink your values for bottom and right.
If you're looking to have the red box protrude from the black box on its right side, consider removing right:0 and applying left:100% instead. This approach guarantees that no matter how wide the black box and red box are, the red box will always be on the outside to the right; they are width-size agnostic. This can be ideal because you may want to change the size of either box dynamically or in the future (it doesn't lock you in to hard set values).
Here's a fiddle of what I'm talking about.
You could use a Z-Index and position one on top of another. There is a better way to do it with Twitter bootstrap code.
http://twitter.github.com/bootstrap/
they give you templates for all kinds of cool features