Why does <a> create a little space under the image? - html

This code leaves this weirdly shaped border (it's the active link border) when you click the image, like so:
And when we put an orange background on the <a> element we see that there's an orange area underneath the image. So, <a> wraps around the image, but also around an area underneath it.
Why does <a> do that?

First, by default element has an 'outline' decoration, to disable it use the following css rule:
a { outline: 0 }
Second, the area is created by another css property you apply on the image itself: 'margin', which is the margin between the image to the elements around it, in this case it affects the element which wraps it, to fix that change the following rules:
.socialBtn {
/* Removed margin here so there won't be space around image */
height: 2.5em;
width: 2.5em;
}
a {
height: 2.5em; /* Gave it width like the image */
width: 2.5em; /* Gave it height like the image */
display: inline-block; /* Made it inline-block so it can have width and height */
}
http://jsfiddle.net/we67Lp6o/6/
UPDATE:
Changing source to understand how the display property: block vs inline-block vs inline.
Removed "outline: 0" from a selector, it is a bad practice, read why here.

It's actually not spacing underneath at all. It's because your a tag is collapsed due to the default setting of display:inline. Adding display: inline-block to those as will fix that issue:
FIDDLE
Alohci offers a great explanation on why this happens
UPDATE
The extra spacing is the margin on the img:
.social a {
display: inline-block;
background-color: orange;
padding: 0;
margin: 0;
vertical-align: top;
}
.socialBtn{
height: 2.5em;
width: 2.5em;
padding: 0;
margin: 0;
vertical-align: inherit;
}
NEW FIDDLE
The spacing answer can be provided here

inline-blockis the property you need for the <a> elements. For the spacing issues, the margins need to be removed.
The reason for the strangely shaped border, is of the outline property on <a>. It's showing you the area of your link, but due to the display and margin properties it is a different size than your img.
Here is the new CSS:
.header {
width: 650px;
height: 150px;
clear: left;
margin: 0px auto;
background-color: #efefef;
position: relative;
border-radius: 4em 4em 0 0;
}
.social{
padding: 1em 2em 0 0;
display: inline-block;
position: absolute;
right: 0;
}
.socialBtn{
height: 2.5em;
width: 2.5em;
}
img {
display: block;
}
a {
display: inline-block;
background-color: orange;
}
http://jsfiddle.net/Lg5a0ksg/4/

Set your images to display: block (or alternatively, to vertical-align: bottom) to remove the default space at the bottom. (By default, images align to the baseline of any potential text next to them, and they leave that space there even if there's no text beside them.)

Related

Heading ::after element always in top right right after text

I have my heading with arrow ::after element. After element is positioned absolute with margin-left:10px, but when i shrink down website the element wraps with text down.
Is there a way for arrow to always stick to top right of heading no matter what width of device like this?
Tried with display inline but it doesnt work. Any idea if it's possible?
I'd wrap the heading in another element and use the ::after pseudo-element of the parent. In my example, I used a <div> with display: inline;, and set the heading's margin-right to 1em to account for the width of the ::after element. My code probably isn't too different from yours, just uses different selectors.
CodePen here: https://codepen.io/the_Northway/pen/GRMyrLR
Edit: adding the Stack Snippet by suggestion - codepen is still useful to change screen size though.
div {
position: relative;
display: inline;
text-align: center;
}
div h3 {
margin-top: 0;
margin-right: 1em;
}
div::after {
position: absolute;
display: block;
width: 1em;
height: 1em;
content: ">";
color: red;
top: 0;
right: 0;
}
body {
display: flex;
height: 100vh;
width: 100vw;
align-items: center;
justify-content: center;
}
<div><h3>Looking for help?</h3></div>

Gap within inline-block elements with different high

I have container with css elements. All of the elements has display: inline-block property. The problem is that one of the element is twice hire than the rest and instead of having two elements on the side I have only one and a lot of white space. This is how it looks:
my css is:
.productBlock {
display: inline-block;
background-color: darkgray;
height: 271px;
width: 161px;
margin: 3px;
}
.productBlock-higher {
background-color: darksalmon;
height: 548px;
width: 161px;
margin: 3px;
display: inline-block;
}
How can I remove the white space and add element another element there?
I would like to add move two elements on the right side of the higher div. It should look like this:
if I understand correctly, you need to set the vertical align top
https://codepen.io/opmasan/pen/vYNvbpZ
.productBlock {
vertical-align: top;
}
I solved it. I added:
.productBlock-higher {
float: left;
}

Even lines over title and before and after subtitle

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>

Displaying three elements inside a <div> in a same line

This is the html code:
<div class="produto_title">
<h2 th:text="${produto.name}"></h2>
Baixar
Comprar <span th:text="${produto.preco}"></span>
</div>
Could anyone give me a hint how to place the three items inside .produto_title in a same line (h2 floating at left and the two a floating at right).
Also, h2 has a border around item and the a is displayed like a button; I want add a line behind crossing all the "line" formed by this three elements, like this:
jsfiddle: https://jsfiddle.net/klebermo/sf7a6fnj/5/
ps.: also, how let the content of tag <span> inside the button, like the text?
An hr is a block element that's essentially just a line with a border.
I'd recommend sticking one of those at the top of the container and giving it a negative margin that vertically centers it in the parent. position: absolute is more trouble than it's worth.
https://jsfiddle.net/JackHasaKeyboard/0juqg4j7/
As for aligning the elements to the left and the right, I'll let you figure that out. There's many ways to accomplish it, the simplest way being with float.
I would look at twitter's bootstrap, specifically the row and col components.
You could do
<div class="row">
<div class="col-md-4">
// something here
</div>
<div class="col-md-4">
// something here
</div>
<div class="col-md-4">
// something here
</div>
</div>
This will all be displayed on the same line, splitting the row into equal thirds
btns{
height: auto; //Fix the span not being in the element
margin-top: 20px; //line everything up with the top of the heading element.
}
As for the line you can make a div and give it a absolute position (remember to give parent a relative position) and then position it accordingly.
.parent{
position: relative;
width: 100%;
}
.line{
height: 4px;
background-color: #000;
position: absolute;
z-index: -1;
top: 50%;
width: 100%;
}
This is a very bare-bones answer but it will be a start for you to go off.
For the first question, you can do that easily by manipulating margin or vertical-align properties. For example, if you put margin: 30px 5px; on your btn elements, it would be on the same line-ish.
Secondly, the <span> problem: if you set fixed width: 60px; of element (in your case .btn_comprar), text would either overflow from button to the right or bottom. Try setting width: 90px; or more on button elements, or height: auto; if you need it to be fixed.
Updated fiddle
First of all, you can't set a fixed width on a button if you want the text to not wrap. I recommend leaving the buttons at a width: auto and using padding to control the spacing around the text. I'd also bundle the styles for both button selectors, as they're exactly the same
Secondly, the only way (I know of) to get items to vertically align while they're float: right is by manually pushing them down, so I recommend making your buttons position: relative and setting a top: 25px;
/* Bundled both buttons together as they share the same styles */
.btn_free,
.btn_comprar {
float: right;
/* width: 60px; Removing this to allow the text to set the button width */
/* height: 20px; Removing this to let the line-height set the button height */
background: silver;
border-radius: 5px;
padding: 1px 15px;
box-shadow: 1px 1px 1px #000;
/* display: block; Removing this as floats are automatically display: block; */
/* text-align: center; Removing this since the text is already setting width */
background-image: linear-gradient(to bottom, #f4f5f5, #dfdddd);
font-family: arial;
font-size: 12px;
line-height:20px;
position: relative; /* Pushing buttons down a bit */
top: 25px;
margin: 0 10px; /* Spacing buttons out */
}
.btn_free:hover,
.btn_comprar:hover{
background-image: linear-gradient(to bottom, #c3e3fa, #a5defb);
}
Thirdly, remember to use a clearfix so the .produto_title container maintains height!
.produto_title:after {
content: "";
display: table;
clear: both;
}
Lastly, rather than using another div to make the line, I'd use the :before psuedo-element on .produto-title (can't use :after if you're also doing a clearfix).
.produto_title:before {
content: '';
height: 1px;
background: #000;
width: 100%;
position: absolute;
left: 0;
top: 50%;
display: block;
}
Here's a working demo:
https://jsfiddle.net/zcqLbg4h/1/

Adding an image to the end of a <li> with text, centering the image vertically with the text

I don't use CSS that often so every time I use it I have to experiment again and figure things by trial and error.
What I'm trying to do is place icon_32 in the same line as: "I made this." The image is 32px high so I wanted to move it down a bit to center it with the line.
After experimenting a bit I found a solution that works on Safari and Chrome but doesn't work in Firefox.
Here's what I'm doing:
CSS
ul, li {
/* spacing */
margin: 0;
padding: 0;
border: 0;
outline: 0;
/* list */
list-style: none;
}
#work_list li {
display: block;
/* spacing */
margin-bottom: 10px;
}
#work_list .icon_32 {
display: inline-block;
position: absolute; /* This doesn't work in Firefox. */
cursor: pointer;
/* spacing */
margin-top: -8px;
margin-left: 8px;
}
HTML
<ul id="work_list">
<li> I made this. <div class="icon_32"></div></li>
<li>I write, sometimes.</li>
</ul>
Because one can't add a padding-top to inline elements, I made the icon's position absolute. The problem with just having it absolute is that I have to manually set the margin-left because the icon doesn't move to the left automatically with the text. By setting display to block on the <li> and display to inline-block on the icon, what I was trying to achieve worked (although I don't fully understand why). This however, doesn't work in Firefox (and I haven't even tested in IE yet).
Is there a proper way to achieve what I'm truing to do that works correctly on all browsers?
Update: How I ended up solving this by using the suggestions from the answers. Thanks a lot for the help!
I didn't want to use line-height because I wanted to preserve the original height of the li. I just got rid of the unnecessary position: absolute and added vertical-align: middle. After doing so, the image was still affecting the height of the li, so I just added an id to the affected li and overwrote the margin-bottom so the sum of its height + bottom margin would equal the sum from the li without the 32px image.
This is how it ended up being:
CSS
ul, li {
/* spacing */
margin: 0;
padding: 0;
border: 0;
outline: 0;
/* list */
list-style: none;
}
#work_list li {
display: block;
/* spacing */
margin-bottom: 10px;
}
#work_list #work_item_icon {
margin-bottom: 3px;
}
#work_list span.icon_32 {
display: inline-block;
cursor: pointer;
/* spacing */
vertical-align: middle;
margin-top: -8px;
margin-left: 8px;
}
HTML
<ul id="work_list">
<li id="work_item_icon">I made this. <span class="icon_32"></span></li>
<li id="work_item_writing">I write, sometimes.</li>
</ul>
There are many ways to do this:
You can use negative margins to even out the difference between the line height and image height. The height of one line of text appears to be 20px; so a margin-top: -6px and margin-bottom: -6px will make the 32px tall image act as if it were 20px:
#work_list img.icon_32
{
vertical-align: middle;
margin-top: -6px;
margin-bottom: -6px;
}
#work_list span.icon_32
{
/* //// SPAN AS IMAGE \\\\ */
display: inline-block;
width: 32px;
height: 32px;
background-image: url(http://dummyimage.com/32x32/cf0/000&text=32x);
/* \\\\ SPAN AS IMAGE //// */
vertical-align: middle;
margin-top: -6px;
margin-bottom: -6px;
}
demo
Alternately, you can set a line height equal to the height of the image and set vertical-align: middle for the image. You can adjust a few pixels using a negative margin-top:
ul, li
{
line-height: 32px;
}
#work_list img.icon_32
{
vertical-align: middle;
margin-top: -4px;
}
#work_list span.icon_32
{
/* //// SPAN AS IMAGE \\\\ */
display: inline-block;
width: 32px;
height: 32px;
background-image: url(http://dummyimage.com/32x32/cf0/000&text=32x);
/* \\\\ SPAN AS IMAGE //// */
vertical-align: middle;
margin-top: -4px;
}
demo
This also work in firefox also please give position:relative to your LI
or it's better to edit your HTML like this:
<ul id="work_list">
<li><span>I made this.<span> <div class="icon_32"></div></li>
<li>I write, sometimes.</li>
</ul>
CSS:
li span, icon_32{
display:inline-block;
}
Try adding this css rule to your li,
li {line-height: #px;}
play around with the line height to get what you want. Also if using line height affects the image add float: left; to it, or take it out of normal flow.
I think your solution will be line-height. You can set this on the li, and it will center the text vertically.
#work_list li {
line-height: 32px;
}
#work_list .icon_32 {
height: 32px;
width: 32px;
}
Give the element containing the icon div relative position and it will make the positioning of the icon relative to that container.
http://jsfiddle.net/9HeNy/
Make the icon_32 element position : relative and it's parent li element line-height : 32px. A demo is above.
Docs for line-height: https://developer.mozilla.org/en/CSS/line-height