diff --git a/src/lib/form-field/_form-field-theme.scss b/src/lib/form-field/_form-field-theme.scss index 3277aac5bb81..1f815b4fb2cd 100644 --- a/src/lib/form-field/_form-field-theme.scss +++ b/src/lib/form-field/_form-field-theme.scss @@ -90,6 +90,12 @@ } } +// Used to make instances of the _mat-form-field-placeholder-floating mixin negligibly different, +// and prevent Google's CSS Optimizer from collapsing the declarations. This is needed because some +// of the selectors contain pseudo-classes not recognized in all browsers. If a browser encounters +// an unknown pseudo-class it will discard the entire rule set. +$dedupe: 0; + // Applies a floating placeholder above the form field control itself. @mixin _mat-form-field-placeholder-floating($font-scale, $infix-padding, $infix-margin-top) { // We use perspective to fix the text blurriness as described here: @@ -97,25 +103,14 @@ // This results in a small jitter after the label floats on Firefox, which the // translateZ fixes. transform: translateY(-$infix-margin-top - $infix-padding) scale($font-scale) perspective(100px) - translateZ(0.001px); + translateZ(0.001px + $dedupe); // The tricks above used to smooth out the animation on chrome and firefox actually make things // worse on IE, so we don't include them in the IE version. - -ms-transform: translateY(-$infix-margin-top - $infix-padding) scale($font-scale); + -ms-transform: translateY(-$infix-margin-top - $infix-padding + $dedupe) scale($font-scale); - width: 100% / $font-scale; -} + width: 100% / $font-scale + $dedupe; -// This is a total duplicate of the mixin above with insignificant values added to the rules. -// This exists because the mixin is used in two places. When Google's CSS Optimizer runs over this -// css (after compiling from sass), it combines those two declarations into one. However, one of -// those places uses `:-webkit-autofill`. When Firefox encounters this unknown pseuedo-class, -// it ignores the entire rule. To work around this, we force one of the delcarations to be -// technically different but still render the same by adding a tiny value to the transform / width. -@mixin _mat-form-field-placeholder-float-nodedupe($font-scale, $infix-padding, $infix-margin-top) { - transform: translateY(-$infix-margin-top - $infix-padding) scale($font-scale) perspective(100px) - translateZ(0.002px); - -ms-transform: translateY(-$infix-margin-top - $infix-padding) scale($font-scale); - width: (100% / $font-scale) + 0.0001; + $dedupe: $dedupe + 0.00001 !global; } @mixin mat-form-field-typography($config) { @@ -188,14 +183,23 @@ } .mat-form-field-can-float { - &.mat-form-field-should-float .mat-form-field-placeholder { + &.mat-form-field-should-float .mat-form-field-placeholder, + .mat-input-server:focus + .mat-form-field-placeholder-wrapper .mat-form-field-placeholder { @include _mat-form-field-placeholder-floating( - $subscript-font-scale, $infix-padding, $infix-margin-top); + $subscript-font-scale, $infix-padding, $infix-margin-top); } .mat-form-field-autofill-control:-webkit-autofill + .mat-form-field-placeholder-wrapper .mat-form-field-placeholder { - @include _mat-form-field-placeholder-float-nodedupe( + @include _mat-form-field-placeholder-floating( + $subscript-font-scale, $infix-padding, $infix-margin-top); + } + + // Server-side rendered matInput with a placeholder attribute but placeholder not shown + // (used as a pure CSS stand-in for mat-form-field-should-float). + .mat-input-server[placeholder]:not(:placeholder-shown) + .mat-form-field-placeholder-wrapper + .mat-form-field-placeholder { + @include _mat-form-field-placeholder-floating( $subscript-font-scale, $infix-padding, $infix-margin-top); } } diff --git a/src/lib/form-field/form-field.scss b/src/lib/form-field/form-field.scss index 9f1b72717736..839d71814d31 100644 --- a/src/lib/form-field/form-field.scss +++ b/src/lib/form-field/form-field.scss @@ -138,6 +138,18 @@ $mat-form-field-default-infix-width: 180px !default; } } +// Server-side rendered matInput with focus or a placeholder attribute but placeholder not shown +// (used as a pure CSS stand-in for mat-form-field-should-float). +.mat-input-server:focus + .mat-form-field-placeholder-wrapper .mat-form-field-placeholder, +.mat-input-server[placeholder]:not(:placeholder-shown) + .mat-form-field-placeholder-wrapper + .mat-form-field-placeholder { + display: none; + + .mat-form-field-can-float & { + display: block; + } +} + // Disable the placeholder animation when the control is not empty (this prevents placeholder // animating up when the value is set programmatically). .mat-form-field-placeholder:not(.mat-form-field-empty) { diff --git a/src/lib/input/input.ts b/src/lib/input/input.ts index cc4f82bc7875..51c0a842b1e2 100644 --- a/src/lib/input/input.ts +++ b/src/lib/input/input.ts @@ -27,6 +27,7 @@ import {Subject} from 'rxjs/Subject'; import {getMatInputUnsupportedTypeError} from './input-errors'; import {MAT_INPUT_VALUE_ACCESSOR} from './input-value-accessor'; + // Invalid input type. Using one of these will throw an MatInputUnsupportedTypeError. const MAT_INPUT_INVALID_TYPES = [ 'button', @@ -50,6 +51,7 @@ let nextUniqueId = 0; exportAs: 'matInput', host: { 'class': 'mat-input-element mat-form-field-autofill-control', + '[class.mat-input-server]': '_isServer', // Native input properties that are overwritten by Angular inputs need to be synced with // the native input element. Otherwise property bindings for those don't work. '[attr.id]': 'id', @@ -86,6 +88,9 @@ export class MatInput implements MatFormFieldControl, OnChanges, OnDestroy, /** The aria-describedby attribute on the input for improved a11y. */ _ariaDescribedby: string; + /** Whether the component is being rendered on the server. */ + _isServer = false; + /** * Stream that emits whenever the state of the input changes such that the wrapping `MatFormField` * needs to run change detection. @@ -187,6 +192,8 @@ export class MatInput implements MatFormFieldControl, OnChanges, OnDestroy, } }); } + + this._isServer = !this._platform.isBrowser; } ngOnChanges() { diff --git a/src/universal-app/kitchen-sink/kitchen-sink.html b/src/universal-app/kitchen-sink/kitchen-sink.html index 6330e55cfc8d..cfb680ee394d 100644 --- a/src/universal-app/kitchen-sink/kitchen-sink.html +++ b/src/universal-app/kitchen-sink/kitchen-sink.html @@ -103,6 +103,10 @@

Icon

Input

+ + + +