I want to put a colorful outline around a bunch of inline elements. Is there any easy way to make this look right within the flow of the text?
Here's the HTML:
<span>Text Before</span>
<div class="border">
<div>This</div>
<div>is</div>
<div>not</div>
<div>a</div>
<div>public</div>
<div>service</div>
<div>announcement.</div>
</div>
<span>Text After</span>
Here's the CSS:
.border {
display: inline;
background-color: pink;
word-spacing: 10px;
padding: 2px 0 2px 0;
border: solid;
}
.border > div {
display: inline;
font-size: 30px;
background-color: lavender;
}
Screenshot with .border display: inline:
Screenshot with .border display: inline-block:
I want it to look roughly like this (accomplished with a mixture of manual line height, padding, and relative positioning... ugh!):
Basically, inline-block elements do everything right, but they don't break apart between lines as would inline elements. But inline elements collapse their height and have to be manually adjusted. Is there really no way around this?
Try adding a line-height on container div.
.border {
display: inline;
background-color: pink;
word-spacing: 10px;
padding: 2px 0 2px 0;
border: solid;
font-size: 30px;
}
.border > div {
display: inline-block;
margin-bottom: 15px;
background-color: lavender;
}
This is a cop-out answer on my part, but It Works™, at least for my purposes, so I'm using it until something better comes up.
If you're willing to commit the relatively minor crime of putting a span around the content of each inner div and setting the text style for the span instead of the div, you can make each of the divs an inline-block, give the background and border style to each individual div instead of the parent div, set the left/right margin of each div, to 0, and extend the borders of the divs via padding to make it seem like one continuous background rect. If you want an outline, you can use the nth-item selectors and set the borders accordingly.
Here's the revised HTML (also compressed onto one line, to get rid of the spaces between inline-block elements):
<span>Text Before</span>
<div class="border">
<div><span>This</span></div><div><span>is</span></div><div><span>not</span></div><div><span>a</span></div><div><span>public</span></div><div><span>service</span></div><div><span>announcement.</span></div>
</div>
<span>Text After</span>
And here's the revised CSS:
.border {
display: inline;
word-spacing: 0;
}
.border > div {
display: inline-block;
vertical-align: middle;
background-color: pink;
padding: 5px;
margin: 2px 0 2px 0;
border-top-style: solid;
border-bottom-style: solid;
}
.border > div:nth-child(1) {
border-left-style: solid;
}
.border > div:last-child {
border-right-style: solid;
}
.border > div > span {
background-color: lavender;
font-size: 30px;
vertical-align: middle;
}
And here's what it looks like:
This technique breaks down if you want something more complex than a background color with a border, but for my purposes, the benefits — those being far simpler CSS and mostly automatic layout — outweigh the cons.
Related
I am trying to get a line over my title that lines up evenly with lines before and after my `sub-title
I looked at two references:
Line before and after title over image
CSS technique for a horizontal line with words in the middle
These helped me get started but I am not sure how to get the top line even with the before and after lines without wrapping despite the length of the title or subtitle.
<div class="title">
<h1>Testingtesting</h1>
</div>
<div class="sub-title">
<h1>Testing</h1>
</div>
<style>
#import url(http://fonts.googleapis.com/css?family=Open+Sans:300);
h1 {
width: 20%;
margin: .7em auto;
overflow: hidden;
text-align: center;
font-weight:300;
color: #000;
}
h1:before, h1:after {
content: "";
display: inline-block;
width: 50%;
margin: 0 .1em 0 -55%;
vertical-align: middle;
border-bottom: 1px solid;
}
h1:after {
margin: 0 -55% 0 .1em;
}
span {
display: inline-block;
vertical-align: middle;
}
.title h1 {
border-top: 1px solid black
}
.title h1:before, .title h1:after {
border-bottom: 0px solid;
}
</style>
You should use white-space: wrap; it should work after using it as you have set width on the element on which you are setting this.
For example,
}
.title h1:after {
content:"\A";
white-space: pre;
}
Explanation
In CSS :after is used to generate some content known as a pseudo-element. The "\A" is interpreted as a line break provided that the white space is preserved, hence you need to set white-space: pre. Finally, the element has to be inline, hence display: inline.
I believe I was able to accomplish what you want with the use of flexbox. TL;DR: see snippet below.
First, I nested div.sub-title within div.title in the HTML.
Then, I turned the div.title into a flex container with display: flex, and set the flow direction to column. Adding align-items: center centers the elements within the container.
Next, I targeted the first h1 element, adding a border-top and border-bottom. You can make it however thick you like—I put 4px. If you want to add or reduce the spacing between the borders and the title, adjust the padding.
I then targeted the div.sub-title container. I gave it a position of relative and then offset its position vertically with top: -45px. You may want to adjust this value to get it centered the way you want it. I applied a zero line-height to remove the default value which is pretty tall on a heading. To adjust the spacing between the sub-title and the line on either side, add padding to div.sub-title—I used 20px. Lastly, add a background color that matches your page's background.
While this works, it'll largely depend on how much pre-defined values you're able to use (like padding and background-color).
Another thing to note is when the screen width gets too small, and the subtitle wraps, it'll look really ugly. This is due to the line-height being set to zero. To fix, you can set a min-width on div.title to prevent the entire container from going below a certain width or reset the line-height in div.sub-title at a certain breakpoint with a media query.
.title {
display: flex;
flex-flow: column nowrap;
align-items: center;
min-width: 350px;
}
.title > h1 {
display: inline;
padding: 30px 0;
border-top: 4px solid black;
border-bottom: 4px solid black;
text-align: center;
}
.sub-title {
position: relative;
top: -45px;
/* reset this w/ a media query when screen size gets too small */
line-height: 0px;
padding: 0 20px;
background-color: #fff;
}
<body>
<div class="title">
<h1>Tomorrow Or Something Longer</h1>
<div class="sub-title">
<h1>Today or something</h1>
</div>
</div>
</body>
I have a child element (h1 in my example) inside a parent div.
Why does the margin of the child appear to be outside of the parent.
The example below:
The child has a padding of 30px and a red border round it as expected.
The div has a yellow background but I expected it to be of height 100 + 30 + the h1 + 30 + 100.
div {
background-color: yellow;
}
h1 {
margin: 100px;
padding: 30px;
border: 5px solid red;
}
<div>
<h1>Child</h1>
</div>
Interestingly if I put a border round the div as in the example below - it behaves as I expected. I know I can work round this, but I would like to know what is going on?
div {
background-color: yellow;
border: 5px solid green;
}
h1 {
margin: 100px;
padding: 30px;
border: 5px solid red;
}
<div>
<h1>Child</h1>
</div>
It's "margin collapsing" which can seem confusing at first.
I recommend you read https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Box_Model/Mastering_margin_collapsing
This can be fixed by applying display: inline-block on the div or the h1. However, I highly recommend using padding on the div in this case, that should solve the problem permanently.
Empty blocks: If there is no border, padding, inline content, height,
or min-height to separate a block's margin-top from its margin-bottom,
then its top and bottom margins collapse. Ref
You can use the outline css property for consistent behavior.
div {
background-color: yellow;
outline: 5px solid green;
}
h1 {
margin: 100px;
padding: 30px;
border: 5px solid red;
}
<div>
<h1>Child</h1>
</div>
When you set the border that means you are telling the DIV container it's boundary.
you have to assign the widths and floats.
float: left;
width: 100%;
Right now the DIV is starting from top. But showing background from the mid.
div {
background-color: yellow;
padding:100px;
}
h1 {
padding: 30px;
border: 5px solid red;
}
<div>
<h1>Child</h1>
</div>
Or this
div {
background-color: yellow;
padding:1px;
}
h1 {
margin:100px;
padding: 30px;
border: 5px solid red;
}
<div>
<h1>Child</h1>
</div>
I'm having trouble keeping two nested inline-blocks aligned without specifying widths. I can get the behavior I want using tables but would prefer to use simpler markup. Here's the basic markup:
<div class="error">
<i></i>
<div class="message">Ruh oh</div>
</div>
Here is the basic css:
.error {
border: 2px solid red;
padding: 8px 10px;
}
i {
display: inline-block;
width: 45px;
vertical-align: middle;
}
.message {
display: inline-block;
vertical-align: middle;
}
Here are the requirements:
.error can be any width (usually 100%)
i will be fixed width (usually 45px)
.message will fill the remaining width of the parent .error
both i and .message will be vertically aligned in the middle
.message cannot wrap under i
no javascript
Here is a fiddle showing a good line (short error), a bad line (longer error messages wrap below the i) and a working example with tables (but I don't want tables). Please enlighten me!
http://jsfiddle.net/3m2db1hw/
you need to use display:table to parent Div and display:table-cell to children i.e. <i> and <div>
.error {
border: 2px solid red;
padding: 8px 10px;
display:table;
}
i {
width: 45px;
vertical-align: middle;
display:table-cell !important;
}
.message {
display: table-cell;
vertical-align: middle;
}
here is edited jsfiddle
http://jsfiddle.net/3m2db1hw/1/
Alright, this one should be pretty easy for you front-end guys out there. I have the styled purple link all set to go. I'm just having trouble getting the vertical line to look OK. Assume the line is 1px #000 solid
I kind-of got it working making a div w/ a bottom-border and floating the styled link to the right. If I do that, I can't seem to get there to be space between the divider line and the link.
The following involves some extra markup and uses table-cells.
HTML:
<div class="wrapper">
<span class="leader">
<b></b>
</span>
<span class="cell">
<button>Sample Button</button>
</span>
</div>
CSS:
.wrapper {
border: 1px dotted gray;
display: table;
width: 100%;
}
.wrapper .leader, .wrapper .cell {
display: table-cell;
vertical-align: middle;
}
.wrapper .leader {
width: 100%;
padding: 0 10px;
}
.wrapper .leader b {
display: block;
border-bottom: 1px solid red;
}
.wrapper button {
white-space: nowrap;
}
Demo at: http://jsfiddle.net/audetwebdesign/8aSBA/
There are a few advantages to this approach:
You can control the spacing to the left and right of the horizontal line
Vertical alignment is independent of font-size, line-height
You don't need to specify the width of the button
You can use a :before selector in css, though im not sure is compatable in < ie7
.button:before {
background: none repeat scroll 0 0 #000000;
content: "";
float: left;
height: 1px;
margin-top: 12px;
width: 59%;
}
I am trying to center align an image that is wrapped in a <span>, but I am having trouble doing so. I have uploaded my CSS and HTML to jsfiddle: http://jsfiddle.net/7nHhu/1/
I am trying to get the image to center align itself with the content in a "block" style (ie. all text above and below it, not wrapped to the left or right)
Any help would be greatly appreciated.
.imgframe {
border: 1px solid #EAEAEA;
display: inline-block;
margin: 8px;
}
.imgframe img {
border: 1px solid #FFFFFF;
margin: 0;
background: #F6F6F6;
padding: 8px;
-moz-box-shadow: 2px 2px 5px #CCCCCC;
-webkit-box-shadow: 2px 2px 5px #CCCCCC;
}
<span class="imgframe centerimg"><img src="http://i48.tinypic.com/31368e9.jpg" /></span>
I think it's more appropriate to use text-align for centering text rather than images. You could center an image by setting left and right margin auto.
img {
display: block;
margin-left: auto;
margin-right: auto;
height: auto;
padding-top: 10px; //margin-top doesn't work
}
Demo
Just make image wrapper block level element and text-align:center; it.
FIDDLE
or wrap it in another element if needed;
FIDDLE
In .imgframe, add width: 100%;
Given your requirements, to keep the .imgframe element in-line, to avoid it taking up the full width of the enclosing element, and working without adding wrapping elements to your mark-up, the following works:
body {
text-align: center;
}
body p {
text-align: left;
}
JS Fiddle demo.
This would, probably, be less intrusive if you had the elements from your Fiddle wrapped in a specific, target-able, element; rather than the body, as the method, above, requires you to reset the text-align for all elements contained within the body. So, personally, I'd use:
<div id="contentWrapper">
<p>...</p>
<span class="imgframe">
<img src="..." />
</span>
<p>...</p>
</div>
And:
#contentWrapper {
text-align: center;
}
#contentWrapper p {
text-align: left;
}
Just in order to minimise the amount of work required to tidy up afterwards.
span {position: absolute; top:0; left: 0; width: 100%; text-align: center;}
img {width:yourimagewidth; heigth: width:yourimageheigth}