Maxwell s.c
Maxwell s.c

Reputation: 1668

Inline-Block inside Inline-block Invisible Margin

See this pen for an example and one solution: https://codepen.io/MaxViewUp/pen/YrXzRG

I have an inline title that will have width acording to the text width, and i have an :after inside it (or an div if you want) with inline-block too and width of 70%. I use inline-blocks because i have 3 variations of this title (left, right and center), so i just change the text direction to change the title.

The problem: The inline-block element is having an strange invisible "margin-top" from the text. I want to know why this is happening and an better solution. I think is something related to the font-size (bigger font size bigger spacing) but i'm not sure.

Solutions until now:

if anyone know exactly why this happens, please explain it.

CSS code:

.main-title {
  display: inline-block;
  font-size: 24px;
}
.main-title:after {
  content: '';
  display: inline-block;
  width: 70%;
  height: 2px;
  background: green;
}
.main-title-wrapper {
  margin: 20px 0;
}
.main-title-wrapper.right {
  text-align: right;
}
.main-title-wrapper.center {
  text-align: center;
}

NOTE I want to solve the problem but i really need is the reason this is happening (documentation, etc). Thanks for helping.

Upvotes: 3

Views: 3010

Answers (5)

Greg Rozmarynowycz
Greg Rozmarynowycz

Reputation: 2085

Solution using relative positioning and giving greater spacing control: https://codepen.io/anon/pen/oGXXmV

By definition of being inline-block, your :after pseudo-element is subject to the text sizing properties uniform to your title element. It is just on a new line, with the same line-height and other properties of the title text.

If you simply reduce the overall line-height of the title, as suggested by other answers, you are really just squishing two lines into the space of one line. No particular problem with this, but could have other unintended side effects depending.

This solution uses em so it will not change relative to your title even if you change the font size to something other than 24px (highly recommend using em in general, much more accessible and adaptable).

.main-title{
	display: inline-block;
	background: #fc0;
	height: 1em; /* tweak this value to control the overall height */
	font-size: 24px;
}
.main-title:after{
  content: '';
  display: inline-block;
  width: 70%;
  height: 2px;
  background: green;
  position: relative;
  top: -.85em; /* tweak this value to control distance of line below text */
}

Upvotes: 1

Patrick Kunka
Patrick Kunka

Reputation: 1048

Each inline or inline-block element on its own line (like your :after) element, will behave like a line of text, and is therefore subject to the line-height, vertical alignment and baseline of whatever font and font-size you've set on the parent (24px).

While it requires an extra element, your initial example solution of wrapping the text in its own element, applying a 0 font-size to parent, and applying the 24px font-size only to the text element (and therefore to that first line only), is the best solution if you don't want to resort to hacks such as negative margins or negative line-heights.

This is a summary of typographic CSS properties as they would apply to inline or inline-block elements: https://iamvdo.me/en/blog/css-font-metrics-line-height-and-vertical-align

Upvotes: 1

Naga Sai A
Naga Sai A

Reputation: 10975

Use line-height to achieve expected result

https://codepen.io/nagasai/pen/jGPEbX

.main-title{
    line-height: 7px;
    display: inline-block;
    font-size: 24px;
}

Line height of the ::after pseudo-element will gets inherited from the main-title class div
Please check out this article with example for reference - http://www.testmycss.com/tips-and-tricks/css-before-pseudo-element-line-height/ and https://developer.mozilla.org/en-US/docs/Web/CSS/line-height

Upvotes: 1

Michael Coker
Michael Coker

Reputation: 53694

You can use inline-flex with flex-direction: column

.main-title {
	display: inline-flex;
	font-size: 24px;
	flex-direction: column;
}
.main-title:after {
	content: '';
	width: 70%;
	height: 2px;
	background: green;
}
.main-title.expected {
	font-size: 0;
}
.main-title.expected > div {
	font-size: 24px;
}

.main-title-wrapper {
	margin: 20px 0;
}

.main-title-wrapper.right {
  text-align: right;
}

.main-title-wrapper.right .main-title {
	align-items: flex-end;
}

.main-title-wrapper.center .main-title {
	align-items: center;;
}

.main-title-wrapper.center {
  text-align: center;
}

* {
	font-family: sans-serif;
	font-weight: 300;
	box-sizing: border-box;
}
CSS problem:

<div class="main-title-wrapper">
 <div class="main-title">Normal</div>
</div>

<div class="main-title-wrapper">
 <div class="main-title">Normal - An Large text...</div>
</div>

<div class="main-title-wrapper right">
 <div class="main-title">Right - Lorem ipsum</div>
</div>

<div class="main-title-wrapper center">
 <div class="main-title">Center - Lorem ipsum</div>
</div>

<div class="main-title-wrapper">
 <div class="main-title expected">
  <div>This is what i expected:</div>
 </div>
</div>

Upvotes: 1

kyun
kyun

Reputation: 10264

.main-title{
    display: inline-block;
    position: relative;
    font-size: 24px;
        &:after{
            content: '';
            position: absolute;
            bottom: 0px;
            left: 0px;
            display: inline-block;
            width: 70%;
            height: 2px;
            background: green;
        }
}

How about using position: relative and position:absolute?

https://codepen.io/anon/pen/QqbwbJ

Upvotes: 1

Related Questions