CSS anchor text-align its content center not working - css

Try to align the div in the center of the link, not working. still align left.
a {
display: block;
text-align: center;
background: green;
}
div {
width: 100px;
background: red;
}
<a>
<div>
Hello World
</div>
</a>

Set the margin to auto on the div and remove the text-align rule on the anchor:
a {
display: block;
background: green;
}
div {
width: 100px;
background: red;
margin: auto;
}
<a>
<div>
Hello World
</div>
</a>

Use display: inline-block; on the div to allow that:
a {
display: block;
text-align: center;
background: green;
}
div {
width: 100px;
background: red;
display: inline-block;
}
<a>
<div>
Hello World
</div>
</a>

Set div style Margin 0 auto
div {
width: 100px;
background: red;
margin: 0 auto;
}
a {
display: block;
text-align: center;
background: green;
}
<a>
<div>
Hello World
</div>
</a>

There are quite a few ways in which this can be achieved; the following code snippet shows a few of those approaches with explanatory comments:
*,
::before,
::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
main {
display: grid;
gap: 1em;
margin-block: 1em;
margin-inline: auto;
width: clamp(10em, 70vw, 1000px);
}
/* styling all <a> elements: */
a {
border: 1px solid lightblue;
padding-block: 0.25em;
}
/* styling all <div> elements: */
div {
border: 1px solid palegreen;
text-align: start;
}
/* using the ::before pseudo-element to
show the 'Hello World string: */
div::before {
content: "Hello World";
display: block;
text-align: center;
}
/* styling all <code> elements: */
code {
/* display: block purely to allow for
padding to be applied on the inline
axis: */
display: block;
/* to show the code as it was written,
including line-breaks: */
white-space: pre;
padding-inline: 1em 0.5em;
}
a.withMarginInline div {
/* using the margin-inline of 'auto' to move the <div>
to the center of its parent: */
margin-inline: auto;
/* setting the width of the <div> to a width which fits its
content, allowing lines to wrap as needed: */
width: fit-content;
}
/* retaining the 'text-align' property of 'center': */
a.withDisplayInlineBlock {
text-align: center;
}
/* displaying the <div> as an inline-block, which allows it
to be positioned as an inline element, but also allows it
to have specified width, height, margin...: */
a.withDisplayInlineBlock div {
display: inline-block;
}
/* setting the <a> parent to flex-box layout: */
a.withDisplayFlex {
display: flex;
/* centering the content of that element (horizontally),
if vertical centering is required then
'align-content: center' could be added, or
'place-content: center' used in place of both: */
justify-content: center;
}
a.withDisplayGrid {
/* using grid layout: */
display: grid;
/* positioning the content vertically and horizontally
in the centre: */
place-content: center;
}
<main>
<a href="#" class="withMarginInline">
<div>
<code>
childElement {
margin-inline: auto;
width: fit-content;
}
</code>
</div>
</a>
<a href="#" class="withDisplayInlineBlock">
<div>
<code>
parentElement {
text-align: center;
}
childElement {
display: inline-block;
}
</code>
</div>
</a>
<a href="#" class="withDisplayFlex">
<div>
<code>
parentElement {
display: flex;
justify-content: center;
}
</code>
</div>
</a>
<a href="#" class="withDisplayGrid">
<div>
<code>
parentElement {
display: grid;
place-content: center;
}
</code>
</div>
</a>
</main>
JS Fiddle demo.
References:
align-content.
border.
box-sizing.
clamp.
content.
display.
justify-content.
margin.
margin-block.
margin-inline.
padding.
padding-block.
padding-inline.
place-content.
text-align.
white-space.
width.

Related

button not aligned with image in div

In the following image , the button (Questions) is lower than the image (white rectangle). They both are inside the same div. Why? The page has a top level css-grid with 3 rows.
.grid-container {
display: grid;
grid-template-rows: [nav-row-start]auto [nav-row-end logo-nav-row-start] auto [logo-nav-row-end content-row-start] auto [content-row-end];
}
.nav-style {
height: 5vh;
/*make nav div take 5% of space of viewport*/
background-color: black;
}
.logo-nav-style {
height: 20vh;
/*make logo-nav div take 20% of space of viewport*/
background-color: gray;
}
.nav-flexbox-container {
display: flex;
flex-direction: row-reverse;
}
.content-style {
height: 75vh;
/*make content div take 75% of space of viewport*/
background-color: white;
}
#nav {
grid-row: nav-row-start/nav-row-end;
margin: 0px;
}
#logo-nav {
grid-row: logo-nav-row-start/logo-nav-row-end;
margin: 0px;
}
#content {
grid-row: body-row-start/body-row-end;
margin: 0px;
}
#profile-pic {
margin: 5px;
}
#mail-icon-pic {
margin: 5px;
}
#stats-icon-pic {
margin: 5px;
}
#logo-image {
/*the max width and max height rule will make the image fit inside the div. If the image is bigger than div, the image will
contract, if the image is smaller than the div, the image will expand*/
max-width: 100%;
max-height: 100%;
}
body {
margin: 0px;
}
<div class="grid-container">
<div id="nav" class="nav-style nav-flexbox-container">
<img id="stats-icon-pic" src="stats_icon.png">
<img id="mail-icon-pic" src="mail_icon.png">
</div>
<div id="logo-nav" class="logo-nav-style">
<img id="logo-image" src="example_logo.png"/>
<button type="button">Questions</button>
<!-- this button is lower than the image-->
</div>
<div id="content" class="content-style">body</div>
</div>
I can't answer the "why" part, but one solution is to add display: flex and align-items: flex-end to .logo-nav-style.
Also, I wouldn't lock .content-style to height: 75vh but use min-height: 75vh instead so the content can expand beyond that.
I'm also confused why you got flex-direction: row-reverse; on your .nav-flexbox-container. Why not just put the elements in the correct order to begin with?
.grid-container {
display: grid;
grid-template-rows: [nav-row-start]auto [nav-row-end logo-nav-row-start] auto [logo-nav-row-end content-row-start] auto [content-row-end];
}
.nav-style {
height: 5vh;
/*make nav div take 5% of space of viewport*/
background-color: black;
}
.logo-nav-style {
height: 20vh;
/*make logo-nav div take 20% of space of viewport*/
background-color: gray;
/* Rickard's addition */
display: flex;
align-items: flex-end;
}
.nav-flexbox-container {
display: flex;
flex-direction: row-reverse;
}
.content-style {
min-height: 75vh;
/*make content div take 75% of space of viewport*/
background-color: white;
}
#nav {
grid-row: nav-row-start/nav-row-end;
margin: 0px;
}
#logo-nav {
grid-row: logo-nav-row-start/logo-nav-row-end;
margin: 0px;
}
#content {
grid-row: body-row-start/body-row-end;
margin: 0px;
}
#profile-pic {
margin: 5px;
}
#mail-icon-pic {
margin: 5px;
}
#stats-icon-pic {
margin: 5px;
}
#logo-image {
/*the max width and max height rule will make the image fit inside the div. If the image is bigger than div, the image will
contract, if the image is smaller than the div, the image will expand*/
max-width: 100%;
max-height: 100%;
}
body {
margin: 0px;
}
<div class="grid-container">
<div id="nav" class="nav-style nav-flexbox-container">
<img id="stats-icon-pic" src="stats_icon.png">
<img id="mail-icon-pic" src="mail_icon.png">
</div>
<div id="logo-nav" class="logo-nav-style">
<img id="logo-image" src="example_logo.png"/>
<button type="button">Questions</button>
<!-- this button is lower than the image-->
</div>
<div id="content" class="content-style">body</div>
</div>

Align text of different size to the bottom

I have two divs with text of different sizes, that I want to align to the bottom.
They do successfully get aligned to the bottom of their parent, but they're not aligned evenly to each other.
Is this solvable?
.container {
display: flex;
height: 50px;
background: pink;
}
.large, .small {
align-self: flex-end;
margin-right: 5px;
}
.large {
font-size: 30px;
}
.small {
font-size: 15px;
}
<div class="container">
<div class="large">Large</div>
<div class="small">Small</div>
</div>
One way would be to put both text DIVs into another wrapper (.inner_container in my snippet below) which gets the settings the texts previously had in order to align to the bottom, and apply display: inline-block; to the text DIVs: inline-blocks align to each other by their baseline by default, which is what you want if I understand correctly:
.container {
display: flex;
height: 50px;
background: pink;
}
.inner_container {
align-self: flex-end;
}
.large,
.small {
display: inline-block;
margin-right: 5px;
}
.large {
font-size: 30px;
}
.small {
font-size: 15px;
}
<div class="container">
<div class="inner_container">
<div class="large">Large</div>
<div class="small">Small</div>
</div>
</div>
As per #Johannes answer it's a good idea to wrap both text divs in another container. But you don't need an align-self: flex-end; declaration for the .inner-container, just add align-items: flex-end; to the parent div. That way, you get one CSS rule less.
display: inline;, like display: inline-block, makes items align themselves by their baselines (based on the item with the biggest height, in this case the .large text) so you could change the <div class="large"> and the <div class="small"> to spans instead of divs. Since the default display property of <span> is inline, you can then skip the display declaration of .large and .small:
.container {
display: flex;
height: 50px;
background: pink;
align-items: flex-end;
}
.large, .small {
margin-right: 5px;
}
.large {
font-size: 30px;
}
.small {
font-size: 15px;
}
<div class="container">
<div class="inner-container">
<span class="large">Large</span>
<span class="small">Small</span>
</div>
</div>

Place box outside of parent

I have an absolutely positioned div containing two divs side by side. When the left div is removed, the right one appears to jump to the left.
Before:
..AABB...
After:
..BB.....
After (desired behaviour):
....BB...
demo:
https://jsfiddle.net/rb3erkqc/10/
To fix this, I want to be able to absolutely position the right div and have the left one follow along.
The easiest way I can imagine is setting the left margin of A to the negative size of A, but I don't think that's possible, because the size of A is unknown and can change.
without knowing more, here is my shot in the dark
$('.container').click(function(){
$('.container div:first-child').remove();
$('.container div:nth-child(1)').remove();
});
.container {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
}
.container > * {
position: relative;
display: inline-block;
border: 1px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div>
<p>Div A</p>
</div>
<div>
<p>Div A</p>
</div>
<div>
<p>Div B</p>
</div>
<div>
<p>Div B</p>
</div>
</div>
Hope this helps
Edit after code snippet was provided:
.abspos {
margin-top: 10%;
display: flex;
align-items: center;
justify-content: center;
flex-direction: row;
width: 100%;
}
.abspos>*:not(input) {
position: relative;
display: inline-block;
border: 1px solid red;
}
.t {
background-color: red;
}
.e {
background-color: yellow;
}
/* Just a hack to be able to toggle asd*/
input {
position: absolute;
top: 0;
margin: 0px auto;
}
input:checked+.t {
display: none;
}
<div class=abspos>
<input type=checkbox>
<div class=t>asd</div>
<div class=e>fasd</div>
</div>
Update 2 with minor changes:
changed display:none to visibility:hidden
this removes the element from the DOM allowing you to manipulate the <div class='.e'></div>
see fiddle below
.abspos {
margin-top: 10%;
display: flex;
align-items: center;
justify-content: center;
flex-direction: row;
width: 100%;
}
.abspos > *:not(input){
position: relative;
display: inline-block;
border: 1px solid red;
}
.t {
background-color: red;
}
.e {
background-color: yellow;
}
/* Just a hack to be able to toggle asd*/
input {
position: absolute;
top: 0;
margin: 0px auto;
}
input:checked + .t {
visibility:hidden; /*remove element from dom to manipulate remaining div*/
}
<div class=abspos>
<input type=checkbox>
<div class=t>asd</div>
<div class=e>fasd</div>
</div>
I found that one can use absolute positioning to make not affect the parent box and then use a css transform to move based on the object's size.
I also added centering for the element outside the box to demonstrate the generality of this approach. Some overflow handling may be necessary in cases where the right side is smaller.
.abspos {
position: absolute;
left: 106px;
top: 57px;
display: flex;
flex-direction: row;
}
.t {
position: absolute;
transform: translate(-100%);
top: 0px;
bottom: 0px;
display: flex;
align-items: center;
}
.t > div {
background-color: red;
}
.e {
background-color: yellow;
}
/* Just a hack to be able to toggle asd*/
input {
position: absolute;
top: -30px;
}
input:checked + .t {
display: none;
}
<body>
<div class=abspos>
<input type=checkbox>
<div class=t><div>asd</div></div>
<div class=e>fasd<br>lova</div>
</div>
</body>

Table-cell element's not accepting max-width value

Following this answer I tried to vertically center my header elements, however I'm having trouble since there's a container element in between that makes sure they're contained within a certain max-width and centered. I applied display: table-cell to this element and now its max-width doesn't work (occupies the whole screen width regardless of its max-width). How to solve this problem?
Markup:
<header class="banner">
<div class="container">
<a class="header__branding" href="<?php bloginfo( "wpurl" ); ?>">
<img src="<?php bloginfo( "template_url" ); ?>/dist/images/baia_logo.svg" />
</a>
<nav class="nav_primary">
<?php wp_nav_menu( array( 'menu' => 'main menu' ) ); ?>
</nav>
</div>
</header>
CSS:
.banner {
height: 160px;
width: 100%;
display: table;
background: url(../images/header.jpg) 50% 50% repeat-x;
}
.container {
max-width: 1500px;
margin-left: auto;
margin-right: auto;
overflow: hidden;
vertical-align: middle;
display: table-cell;
}
.header__branding {
float: left;
width: 150px;
height: 52px;
display: block;
}
.nav_primary {
float: right;
}
Here is an answer to your question exactly. I will leave the old one as an alternative.
The problem
From CSS 2.2 Specification:
In CSS 2.2, the effect of 'min-width' and 'max-width' on tables, inline tables, table cells, table columns, and column groups is undefined.
So it seems there is no way of adding a max-width to a table-cell currently. You could add a table-cell to each side of the container and set a 1500px width to the container with media queries but this isn't preferred as there is a workaround.
A solution
If you want to limit the width of the nav provided in your link to 1500px you can add a container like you did but the block structure should be a little different.
Now you have:
banner as a table
container as a table-cell
header_branding and nav_primary as blocks inside the cell
Consider changin the structure to following:
banner to a block
container to a table
header_branding and nav_primary to table-cells
The banner is only a 100% wide background element.
Then give the container a max-width of 1500px like you did but remember to give it a 100% width also. Otherwize it wont try to expand to the whole width of the screen as it doesn't have to but now the max-width will be a limiting factor.
Here is a CodePen example provided here but with a container limiting the width to 1500px.
Your example modified:
.banner {
width: 100%;
}
.container {
max-width: 1500px;
width: 100%;
height: 160px;
margin: auto;
overflow: hidden;
display: table;
}
.header_branding, .nav_primary {
vertical-align: middle;
display: table-cell;
}
.header_branding {
width: 150px;
height: 52px;
}
.nav_primary {
text-align: right;
}
/* To make edges visible for the demo */
.banner, .container, .header_branding, .nav_primary {
background: rgba(0, 0, 0, 0.3);
border: 1px dotted red;
}
<header class="banner">
<div class="container">
<a class="header_branding" href="">
<img src="" />
</a>
<nav class="nav_primary">
[Menu items]
</nav>
</div>
</header>
You can define a height or max-height for .container then use flex on header:
.banner {
height: 300px;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.container {
max-width: 500px;
margin-left: auto;
margin-right: auto;
overflow: hidden;
}
CodePen: http://codepen.io/theblindprophet/pen/NAzAWj
This will not work for some versions of IE, check here for details.
With display: inline-block:
/* This parent can be any width and height */
.block {
text-align: center;
/* May want to do this if there is risk the container may be narrower than the element inside */
white-space: nowrap;
}
/* The ghost, nudged to maintain perfect centering */
.block:before {
content: '';
display: inline-block;
height: 100%;
vertical-align: middle;
margin-right: -0.25em; /* Adjusts for spacing */
}
/* The element to be centered, can also be of any width and height */
.centered {
display: inline-block;
vertical-align: middle;
width: 300px;
}
CodePen: http://codepen.io/theblindprophet/pen/XKYKdy
Reference: CSS Tricks
Maybe a
box-sizing: border-box;
property is what you are looking for ;)
One possibility to vertically align elements inside the container it to use line-height as you know the height of your header. The downside of this is that you cannot have more than one row of text but usually this is the intent in the first place.
I tried to strip your code to the minimum and made a working demo here.
Basically if the container is 160px tall you can add line-height of 160px for the menu items to vertically align them to the middle.
To vertically align your image, I used the accepted method from this question.
To future proof, here is the code used in my demo:
* {
margin: 0; /* Illustrative */
padding: 0; /* Illustrative */
}
.banner {
background: #222; /* Illustrative */
width: 100%;
}
.container {
background: #aaa; /* Illustrative */
max-width: 800px; /* Change to desired value */
margin: auto;
overflow: hidden;
}
.header__branding {
background: #555; /* Illustrative */
float: left;
width: 150px;
height: 160px;
display: block;
}
.header__branding span {
height: 100%;
display: inline-block;
vertical-align: middle;
line-height: 160px;
}
.nav_primary {
float: right;
}
.nav_primary a {
line-height: 160px;
}
img {
background: #3867EA; /* Illustrative */
width: 100px; /* Illustrative */
height: 100px; /* Illustrative */
vertical-align: middle;
display: inline-block;
}
<header class="banner">
<div class="container">
<a class="header__branding" href="#">
<img alt="Logo" /><span>Title</span>
</a>
<nav class="nav_primary">
<a>Menu1</a> <a>Menu2</a> <a>Menu3</a>
</nav>
</div>
</header>

Is there a "clearfix" for vertical-align?

Is there a similar technique like float and clearfix but for vertical alignment.
I want to separate different elements (either inline or floating left) such that they are always aligned either to the top or bottom.
In this jsFiddle I want the red and the green to be horizontally aligned. I cannot change the CSS or the existing divs. I can only wrap .s1 and .s2
Ok.. If you know the class name you can do like this:
SEE DEMO 1
Here the css:
.s1 {
display: inline-block;
font-size: 10px;
height: 20px;
}
.s2 {
display: inline-block;
background: green;
font-size: 20px;
height: 20px;
}
.s3 {
background: red;
height: 20px;
}
/* PUT THIS IN AN EXTRA FILE OR UNDER THE ABOVE STYLE */
.s1 {
vertical-align: bottom;
}
.s2 {
vertical-align: middle;
}
Or if you can wrap the file you can float the div's like this:
SEE DEMO 2
HTML
<div class="wrap_1"> <!-- Wrap 1 -->
<div class="s1">
<div class="s3">asdf</div>
</div>
</div>
<div class="wrap_2"> <!-- Wrap 2 -->
<div class="s2">
<div>qwer</div>
</div>
</div>
CSS
.s1 {
display: inline-block;
font-size: 10px;
height: 20px;
}
.s2 {
display: inline-block;
background: green;
font-size: 20px;
height: 20px;
}
.s3 {
background: red;
height: 20px;
}
/* FLOAT THE DIV */
.wrap_1 div, .wrap_2 div {
float: left;
}
Let me know if solved your issue!

Resources